3

Before the activity get's killed (when OnDestroy is called), I am saving some int values in SharedPreferences.

But what I have noticed is that it takes about a second for the values to be saved but the app doesn't wait for that before destroying the Activity.

Can I do some kind of Wait before it gets killed?

Here's my example:

@Override
public void onDestroy(){

    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putInt("finalXPos", finalX);
    editor.putInt("finalYPos", finalY);
    editor.commit();

    super.onDestroy();
    removeView();
}

======================>> EDIT <<======================

I made a mistake and said this was for an Activity but it's not. I am calling the onDestroy of a Service and unfortunately there is no onPause method to override there...

hata
  • 11,633
  • 6
  • 46
  • 69
ᴛʜᴇᴘᴀᴛᴇʟ
  • 4,466
  • 5
  • 39
  • 73
  • 2
    Use apply instead of commit. See here for explanation : http://stackoverflow.com/questions/5960678/whats-the-difference-between-commit-and-apply-in-shared-preference – NecipAllef Sep 15 '15 at 02:33
  • Take a look at the edit and see if it helps ;) – Mauker Oct 04 '15 at 13:22

2 Answers2

10

As per the docs, don't rely on the onDestroy() method to persist your data. Use onPause() instead.

Note: do not count on this method being called as a place for saving data!

For example, if an activity is editing data in a content provider, those edits should be committed in either onPause() or onSaveInstanceState(Bundle), not here. This method is usually implemented to free resources like threads that are associated with an activity, so that a destroyed activity does not leave such things around while the rest of its application is still running.

There are situations where the system will simply kill the activity's hosting process without calling this method (or any others) in it, so it should not be used to do things that are intended to remain around after the process goes away.

Also, you could try to use the method apply() instead of commit() on your SharedPreferences.Editor because it saves your data faster, asynchronously, and there's no return value to handle at all.


EDIT: Ok, so you're using a Service. Problem is, their lifetime can outlast an Activity life by far, as they keep running in the background. So the onDestroy() of your service can take a very long time before it gets called, even if you close your app with the back button.

I'm not sure how your app is supposed to work, but I can suggest a few things.

  1. If you want to work on your SharedPreferences when the user closes the app, move that method to an Activity or;
  2. Inside the Activity#onPause() you can destroy the Service using the stopService() method. (See example below).
  3. If your Service is supposed to do some work and if after this work is done it should modify the SharedPreferences, you could try to use an IntentService, because once this kind of Service finishes its job, it'll destroy itself. But take note, only one IntentService can run at a time! It runs on a FIFO queue.
  4. If you don't want to use an IntentService, you could also call stopSelf() from within your regular Service to stop it and destroy it.

Example on finishing a Service:

@Override
protected void onPause() {
    super.onPause();
    stopService(new Intent(context, YourService.class));
}

More info about IntentService on this tutorial. More info on a Service lifecycle on this link.

Mauker
  • 11,237
  • 7
  • 58
  • 76
  • That is a very good suggestion but unfortunately doesn't work for me. There is no `onPause()` in my case because this is not an `Activity`. I made a mistake. This is a `Service` and for `Service`, there is only `onCreate`, `onStart` and `onDestroy` methods... http://developer.android.com/reference/android/app/Service.html – ᴛʜᴇᴘᴀᴛᴇʟ Sep 15 '15 at 04:23
  • Well, take a look at the edit then. It might help. @th3pat3l – Mauker Sep 15 '15 at 14:40
2

onDestroy in Service can be reached by explicitly calling stopService() method.

Although you want to clear Shared Preferences in the Service, that's really not reliable. I'm sure there would be an Activity that starts the Service.

I'd make a method in that Activity, like this.

 private void stopService() {
    stopService(new Intent(getApplicationContext(), MyService.class));
 }

and whenever you want to actually kill the app, you can call along with the stopService(..) call like..

private void stopService() {
    clearPref();
    stopService(new Intent(getApplicationContext(), MyService.class));
}

private void clearPref() {
    // Clearing all data from Shared Preferences
    editor.clear();  // where editor is an Editor for Shared Preferences
    editor.commit();
}

For Service, you need to think about multiple scenarios of the life cycle of the app. It's often hard to think of situations, but I'm sure you will be able to figure out. Good luck!

Saehun Sean Oh
  • 2,103
  • 1
  • 21
  • 41