I had a simple application, with an activity and a service.
The activity have a toggle button to start and stop the service. The service have a notification to show when it is up, and when it is down. The notification text is set by the activity, stored in SharedPreferences
, and read inside service onCreate()
.
The toggle button save a boolean serviceStarted
when starting/stopping the service, so when the activity start, I can restart the service if it was started previously.
My bug is: sometimes, the serviceStarted
is not saved properly. I can see this by looking at the sharedPreferences file. It works most of the time, but from times to times, it just didn't work. The SharedPreferences instance have correct values, but the file is not correct. And event less frequently, but it happens, the preferences xml file totally disappears.
My preference file only have two values: the serviceStarted
boolean, and a short string with the notification text.
The toggle's click listener is:
public void onClick(View v)
{
ToggleButton toggle = (ToggleButton) v;
boolean mustStartService = toggle.isChecked();
if(mustStartService)
{
Intent serviceIntent = new Intent(MainActivity.this, MainService.class);
startService(serviceIntent);
}
else
{
Intent serviceIntent = new Intent(MainActivity.this, MainService.class);
stopService(serviceIntent);
}
// Save to SharedPreferences
SharedPreferences settings = getSharedPreferences("prefs", Context.MODE_MULTI_PROCESS);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("serviceStarted", mustStartService);
editor.commit();
}
Notes:
The service is put in another process, so the system can relese the resources from the activity once it is gone, thus keeping the service/notification up with less resources. Because of that, I use the flag
MODE_MULTI_PROCESS
.The
commit()
call returnstrue
, even if the write does not seem to be correct, or when the file is deleted. I do not have any error fromSharedPreferencesImpl
in the logcat.The only other place where the preferences are written is from listener in the activity (when a TextView is changed), but I never called this code when the bug occurs, so there should not be a write conflict. The service never writes preferences.
The two objects are defined like this in the manifest:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service
android:name=".MainService"
android:process=":mainService"
android:exported="false">
</service>
Any help will be apreciated. I know I can use another way to store preferences, as suggested here, but I would like to know if I am not missing something.