SharedPreference committed in SyncAdapter not updated in Activity?

后端 未结 3 1099
日久生厌
日久生厌 2021-02-19 06:35

I am changing and committing a SharedPreference in my SyncAdapter after successful sync, but I am not seeing the updated value when I access the preference in my Activity (rathe

相关标签:
3条回答
  • 2021-02-19 07:22

    Ok, I figured it out myself with @Titus help and after some research and pieced together a solution for my problem.

    The reason why the DefaultSharedPreferences of the same Context are not updated is that I have specified the SyncService to run in its own process in the AndroidManifest.xml (see below). Hence, starting from Android 2.3, the other process is blocked from accessing the updated SharedPreferences file (see this answer and the Android docs on Context.MODE_MULTI_PROCESS).

        <service
            android:name=".sync.SyncService"
            android:exported="true"
            android:process=":sync"
            tools:ignore="ExportedService" >
            <intent-filter>
                <action android:name="android.content.SyncAdapter" />
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/syncadapter" />
        </service>
    

    So I had to set MODE_MULTI_PROCESS when accessing the SharedPreferences both in the SyncAdapter and in the UI process of my app. Because I've used PreferenceManager.getDefaultSharedPreferences(Context) extensively throughout the app I wrote a utility method and replaced all calls of PreferenceManager.getDefaultSharedPreferences(Context) with this method (see below). The default name of the preferences file is hardcoded and derived from the Android source code and this answer.

    public static SharedPreferences getDefaultSharedPreferencesMultiProcess(
            Context context) {
        return context.getSharedPreferences(
                context.getPackageName() + "_preferences",
                Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS);
    }
    
    0 讨论(0)
  • 2021-02-19 07:22

    In my case I was trying to access SharedPreferences from a service launched by a BroadcastReceiver.

    I removed android:process=":remote" from the declaration in the AndroidManifest.xml to get it to work.

    <receiver 
        android:process=":remote" 
        android:name=".Alarm">
    </receiver>
    
    0 讨论(0)
  • 2021-02-19 07:34

    Since the SharedPreferences are not process-safe, i wouldn't recommend to use the AbstractThreadedSyncAdapter in another process unless you really need it.

    Why do i need multiple processes in my application?

    Solution

    Remove android:process=":sync" from the Service that you declared in your manifest!

    <service
        android:name=".sync.SyncService"
        android:exported="true"
        android:process=":sync"
        tools:ignore="ExportedService" >
        <intent-filter>
            <action android:name="android.content.SyncAdapter" />
        </intent-filter>
        <meta-data
            android:name="android.content.SyncAdapter"
            android:resource="@xml/syncadapter" />
    </service>
    
    0 讨论(0)
提交回复
热议问题