Ten, IPC manner in Android (2) --- the use of file-sharing

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/yz_cfm/article/details/90380905

    Android is a Linux-based system, it concurrent read / write files without any restrictions, so the two threads or two processes can simultaneously write to the same file, although this might be missing some data can not be estimated. So in the Android system, is one of the shared file IPC ways, such as through two processes read / write to the same file to exchange data, of course, here in addition to a number of foreign exchange text messages, it can also store implements the Serializable interface or interfaces Parcelable objects, look at the following example:

User.java:

package com.cfm.filesharingtest;
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    private int mId;
    private String mName;
    private String mDream;

    public User(int id, String name, String dream) {
        mId = id;
        mName = name;
        mDream = dream;
    }

    public int getId() {
        return mId;
    }

    public String getName() {
        return mName;
    }

    public String getDream() {
        return mDream;
    }
}

FirstActivity.java:

package com.cfm.filesharingtest;
public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);

        Button btn = findViewById(R.id.first_btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setClass(FirstActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();

        // 动态申请文件读写权限
        if (ContextCompat.checkSelfPermission(FirstActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(FirstActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        } else {
            storageToFile();
        }
    }

    private void storageToFile() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                User user = new User(666, "cfm", "world peace!");
                File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() + "/cfmtest/");
                if (!dir.exists()) {
                    dir.mkdirs();
                }

                File storageFile = new File(dir, "test");
                ObjectOutputStream outputStream = null;

                try {
                    outputStream = new ObjectOutputStream(new FileOutputStream(storageFile));
                    outputStream.writeObject(user);
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (outputStream != null) {
                            outputStream.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    // 权限申请后的回调
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    storageToFile();
                } else {
                    Toast.makeText(this, "权限被拒绝", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
        }
    }
}

SecondActivity.java:

package com.cfm.filesharingtest;

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }

    @Override
    protected void onResume() {
        super.onResume();
        obtainObjetcWithFile();
    }

    private void obtainObjetcWithFile() {

        new Thread(new Runnable() {
            @Override
            public void run() {
                File filePath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() + "/cfmtest/" + "test");
                Log.d("cfmtest", "文件存储目录: " + Environment.getExternalStorageDirectory().getPath());

                // 反序列文件中的对象
                ObjectInputStream inputStream = null;
                try {
                    inputStream = new ObjectInputStream(new FileInputStream(filePath));
                    User user = (User) inputStream.readObject();
                    Log.d("cfmtest", "反序列化后的 User Id: " + user.getId());
                    Log.d("cfmtest", "反序列化后的 User Name: " + user.getName());
                    Log.d("cfmtest", "反序列化后的 User Dream: " + user.getDream());
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (inputStream != null) {
                            inputStream.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

AndroidManifest.xml:

...
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
...
<activity android:name=".SecondActivity"
    android:process=":remote">
</activity>
...

Print Log Information:

cfmtest: 文件存储目录: /storage/emulated/0
cfmtest: 反序列化后的 User Id: 666
cfmtest: 反序列化后的 User Name: cfm
cfmtest: 反序列化后的 User Dream: world peace!

    To share data through file-sharing in this way there is no specific requirements for the file format, it can be a text file or an XML file, as long as the read / write data format to the two sides agreed. IPC But this approach also has limitations, such as the example above, if we are concurrent read, then read the contents of it may not be the latest, if concurrent write more serious. So if you use this IPC way, you should try to avoid concurrent read / write such a case, or to restrict the use of thread synchronization of multiple threads write operation. To sum up: File sharing for communication between the data synchronization process less demanding, and to properly handle the issue of concurrent read / write.

    Note: In essence, SharedPreferences also belongs to a file, but since Android System to its read / write caching strategies have certain, that there will be a cache memory SharedPreferences file, so in multi-process mode, the system its read / write becomes unreliable when faced with high concurrent read / write access, SharedPreferences have a great chance of data loss, therefore, it is not recommended for use in SharedPreferences interprocess communication.

    To sum can be drawn: the advantages of file sharing is simple to use, the disadvantage is not suitable for high concurrency scenarios, and can not do real-time inter-process communication. It is suitable for non-concurrent access scenarios, a simple exchange of real-time data is not high scene.

Guess you like

Origin blog.csdn.net/yz_cfm/article/details/90380905