Reputation: 513
In my situation, there is one case in which I need to make sure the activity only runs one at a time.
I found if I set the LauchMode
of the activity, I can reach the single instance aim, but it won't update the view of the activity.
This activity is launched by startActivityForResult
, and we send the URI with the intent to the activity.
Let's discuss with this certain case:
gallery - lauch this activity with imageA.
camera - lauch this activity with imageB.
My request is not to destroy the old activity, but the activity that just received the new intent infomation should refresh the view.
I found a new method, onNewIntent
.
This method can refresh the intent before resume. I will try it.
Upvotes: 51
Views: 54571
Reputation: 60923
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
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.
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)
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
Upvotes: 7
Reputation: 515
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.
Upvotes: 40
Reputation: 11230
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" />
Upvotes: 92