Reputation: 2312
I've seen many questions in regards to this "issue" but there aren't any with an actual answer that works flawlessly.
In my app (fitness related) I issue a notification when the user leaves it during a workout so that he can quickly return to it.
Intent intent = new Intent(ctx, WorkoutActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.setClass(ctx, WorkoutActivity.class);
return new NotificationCompat.Builder(ctx)
.setOngoing(true)
.setAutoCancel(true)
.setContentIntent(PendingIntent.getActivity(ctx, 0, intent, 0))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSmallIcon(icon);
Now this works just fine. Thanks to the Intent
flags the activity is resumed if it's up and running.
However the problem I'm seeing is that whenever the app has been in the background long enough and the OS decides to kill it; entering it through the notification will start a new instance of the activity - losing all data. Here are the two ways of re-entering the app after it being in the background, including the behaviour I'm looking for.
Additionally I am saving all state in onSaveInstanceState
and restoring it as per android standard with the savedInstanceState
variable in onCreate
.
Here's the relevant part of the manifest:
<activity
android:name="workout.progression.ui.workout.WorkoutActivity"
android:parentActivityName="workout.progression.ui.MainActivity"
android:theme="@style/AppTheme.WorkoutActivity"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden"/>
And here's the root activity:
<activity
android:name="workout.progression.ui.MainActivity"
android:label="@string/app_name"
android:windowSoftInputMode="stateAlwaysHidden|adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
Upvotes: 2
Views: 712
Reputation: 447
There is no way to prevent an activity from being killed by the OS, however, you can persist that data onto something else like SharedPreferences, a Database or to a file. Here's a guide on how to persist data: Storage Options.
Alternately, you can use a different launch mode such as singleTask:
The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the system routes the intent to existing instance through a call to its onNewIntent() method, rather than creating a new one.
or singleInstance:
Same as "singleTask", except that the system doesn't launch any other activities into the task holding the instance. The activity is always the single and only member of its task.
This can however, mess a little with how your app and activity flow is handled.
References:
Storage Options
Activity Elements: Launch Modes
Upvotes: 1