How to keep a single activity instance but be able to update the view?

Solution 1:

You can have an Activity with a manifest attribute of singleInstance. As soon as the activity is relaunched , onResume gets called. You can update the view with the new image and invalidate the older View.

<activity ..
      android:launchMode= "singleInstance" />

Solution 2:

In your manifest, use android:launchMode="singleTask" instead of android:launchMode="singleInstance". Using singleInstance only returns to the existing instance if it is at the top of the stack. singleTask, on the other hand, return to the existing instance of the activity, as it is always at the root of the task.

Then, when your instance is launched, override onNewIntent to update your UI according to the new intent.

Refer to the Andorid documentation for details.

Solution 3:

Be careful when using android:launchMode="singleInstance" in multiple activities application.
Here is my test on Pixel 4XL (Android 10)
Example, we have 3 activities (without declare taskAffinity)

  • A (entry activity)
  • B (start from A)
  • C (singleInstance, start from B)

If we start A->B->C. Now A,B in a task and C in a different task.
From C, press back -> will see B, press back -> will see A, press back -> app close. Everything working efine.

However, if we start A->B->C then press Home -> app go to to background. Now there is 2 situations

  • User open app again from Recent app.
    • User will see C screen. Press back -> app will close (don't go to B)
  • User open app again by click on app icon
    • User will see B screen. Press back -> will see A, press back -> app will close (don't go to C)

The behaviour after open application is different between both case. But in both case, the application is always available in Recent app and you never able to remove application from Recent app (after remove it will appear again). Only able to remove it by Force stop in Setting.
If you run adb shell dumpsys activity activities, you will see that activities still exist in Stack, but you can not go back to it.

Another case

If we start A->B->C->A. Now A,B,A in a task and C in a different task (A is current visible to user).
From A, press back -> will see B (not C), press back-> will see A, press back -> will see C, press back -> app will close. (at least here we can go back to C)

Now if, we start A->B->C->A then press Home. In both case, user open app again by Recent or click on app icon, user will see A screen. Press back -> will see B, press back -> will see A, press back -> app will close (never see C screen)

Another note

The above example, although application run on 2 tasks but in Recent apps, it only show 1 task. If you set the taskAffinity, in the Recent apps, you will see 2 tasks. In that case, you can choose the task which contain activity that you want to display but when you press back, it just go back to the activity in same task or close app (not able to go back to activity in another task). Also, if you click on app icon to open app again, we have the same behavior like above demo.

I think singleTask and singleTop is less complex than singleInstance, so if it is enough for solve your problem, consider to use them instead of singleInstance