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
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);
}
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>
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>