Use SharedPreferences on multi-process mode

前端 未结 7 886
不思量自难忘°
不思量自难忘° 2020-12-13 14:50

I\'ve defined an instance of SharedPreferences that used on multi-process mode.

public class Prefs {

    private static SharedPreferences pref         


        
相关标签:
7条回答
  • 2020-12-13 15:15

    There is currently no way of safely accessing SharedPreferences on multiple processes, as described in its documentation.

    Note: This class does not support use across multiple processes.

    After testing a lot with MODE_MULTI_PROCESS, I've three trials to share:

    1- Initialize the SharedPreferences once in each process and use it multiple times.

    The problem: The values are not reflected in each process as expected. So each process has its own value of the SharedPreferences.

    2- Initialize the SharedPreferences in each put or get.

    This actually works and the value now is interchangeable between processes.

    The problem: sometimes after aggressively accessing the sharedpref, the shared preferences file got deleted with all its content, as described in this issue, and I get this warning in the log:

    W/FileUtils﹕ Failed to chmod(/data/data/com.hegazy.multiprocesssharedpref/shared_prefs/myprefs.xml): android.system.ErrnoException: chmod failed: ENOENT (No such file or directory)
    

    You can find why this happens in the issue.

    3- Use synchronization to lock the methods that put and get values in the SharedPreferences.

    This is completely wrong; synchronization doesn't work across processes. The SharedPreferences is actually using synchronization in its implementation, but that only ensures thread safety, not process safety. This is described very well here.

    0 讨论(0)
  • 2020-12-13 15:15

    I've worked around this by combining:

    • Providing each process mutually-exclusive access to the SharedPreferences file (such as by using a socket-based locking mechanism)
    • Re-initialising the SharedPreferences with the MODE_MULTI_PROCESS flag every time you want to use it to bypass in-memory caching

    This seems to work OK, but it hasn't been thoroughly tested in the real world, so I don't know if it's perfectly reliable.

    You can see a working example I wrote here.

    Warning: Looks like MODE_MULTI_PROCESS has been deprecated in Android M. It might stop working in the future.

    0 讨论(0)
  • 2020-12-13 15:19

    SharedPreferences itself is not process-safe. That's probably why SharedPreferences documentation says

    Note: currently this class does not support use across multiple processes. This will be added later.

    0 讨论(0)
  • 2020-12-13 15:28

    If two processes write data to SharedPreferences, then it might possible all SharedPreferences are reset to default values.

    Also you can try to call clear() on the editor before storing val

    SharedPreferences.Editor sp = settings.edit();
    sp.clear();
    sp.putString("Name", "YourName");
    sp.commit();
    
    0 讨论(0)
  • 2020-12-13 15:32

    recalls that the use of context objects as static field, you have the risk of leakage of context because not declare the object in the application class

    public class CustomApplication extends Application{
         private Prefs prefs;
    
         public void onCreate(){
              prefs = new Prefs(this);
         }
    
         public Prefs getPrefs(){
            return prefs;
         }
    }
    

    From any context you can get the prefs

       ((MyApplication)context.getApplicationContext()).getPrefs();
    
    0 讨论(0)
  • 2020-12-13 15:34

    Using the commit() method store the changes in persistent storage, hence it is slow and would make conflict across multiple call from other processes.

    However there is an alternative to this method, you should call the apply() method, this method stores the changes in memory and then in disk storage asynchronously, so it is more reliable.

    0 讨论(0)
提交回复
热议问题