Sending intent to an activity that killed itself - android

Suppose I start with Activity A which invokes Activity B. So the Task looks like A->B with B at the top.
B sends an intent to start Activity C and after sending the intent to C, B invokes finish() on itself. So the stack would look like A->C.
Now when I was sending an intent to Activity B with the flag FLAG_ACTIVITY_NEW_TASK, I noticed its onCreate() wasn't called. But when I added the flag FLAG_ACTIVITY_CLEAR_TOP along with the aforementioned one, it worked.
2 questions:
Why didn't it work with just FLAG_ACTIVITY_NEW_TASK ?
What changed with FLAG_ACTIVITY_CLEAR_TOP ?
I have gone through the official documentation of both the flags but cannot co-relate the explanation with the above scenario.

Related

How to set no History for all Activities

My Android Application is based on four Activities. The last activity starts an Intent Service and set itself to background.
Before I sent the last Activity to background I would like to remove all four Activities from backstack history
I tried already to set the no history = true attribute for the activities. This causes errors when I use startActivityForResult, so I need a different solution
I don't really think there is an "good" way to do this, I would try something like this:
First create a SelfClosingActivity which only job is to close itself after opening:
public void onCreate(Bundle savedInstanceState()) {
super.onCreate(savedInstanceState);
finish();
}
When you want to close all the Activities (after you start your IntentService I guess) run the SelfClosingActivity and add flags to clear the current stack.
Intent intent = new Intent(this, SelfClosingActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
This will clear the current stack before opening SelfClosingActivity and SelfClosingActivity will close itself leaving the stack completely empty.
FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_NEW_TASK will do what you want.
FLAG_ACTIVITY_CLEAR_TOP
Added in API level 1 int FLAG_ACTIVITY_CLEAR_TOP If set, and the
activity being launched is already running in the current task, then
instead of launching a new instance of that activity, all of the other
activities on top of it will be closed and this Intent will be
delivered to the (now on top) old activity as a new Intent.
For example, consider a task consisting of the activities: A, B, C, D.
If D calls startActivity() with an Intent that resolves to the
component of activity B, then C and D will be finished and B receive
the given Intent, resulting in the stack now being: A, B.
This launch mode can also be used to good effect in conjunction with
FLAG_ACTIVITY_NEW_TASK: if used to start the root activity of a task,
it will bring any currently running instance of that task to the
foreground, and then clear it to its root state. This is especially
useful, for example, when launching an activity from the notification
manager.
Refer to Tasks and Back Stack for more info

Finishing multiple activities to resume an old one in stack?

I need to finish multiple activities in stack and resume an old one. For example,
There are four activities in stack Act1, Act2, Act3 and Act4. On some event in Act4, I need to finish Act4, Act3 and Act2 to resume Act1.
I tried using Intet.FLAG_ACTIVITY_CLEAR_TOP but it's recreating the activity which is not my requirement.
Advance thanks for suggestions.
You have used Clear_top, it will clear all the activities and bring act1 to front, but, onNewIntent method will be called of you activity, you can perform any task you want in that, after activity starts again.
Or, you can use flag FLAG_ACTIVITY_REORDER_TO_FRONT with your intent, it will do:
FLAG_ACTIVITY_REORDER_TO_FRONT do this:If set in an Intent passed to Context.startActivity(), this flag will cause the launched activity to be brought to the front of its task's history stack if it is already running.
FLAG_ACTIVITY_CLEAR_TOP will do: If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.
for more information on flags look
http://developer.android.com/reference/android/content/Intent.html
There are four activities in stack Act1, Act2, Act3 and Act4. On some
event in Act4, I need to finish Act4, Act3 and Act2 to resume Act1.
Do this:
Intent intent = new Intent(Act4.this, Act1.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
use android:launchMode,will be ok.
<Act1
...
android:launchMode="singleTask">

Android:Delete a activity in backstack

I have got 4 activity let it be A->B->C->D.In every A,B,C activity user need to enter data all data will sent to server in C activity if the user data is correct he will move on to D activity and all the activity A,B,C removed from stack.If the data is in correct i need give the user to reenter data i.e is on back press it has to move C->B->A.My question is How to remove A,B,C activity when user enter D activity.
Use FLAG_ACTIVITY_CLEAR_TOP this shall solve your problem
From the Android documentation:
If set, and the activity being launched is already running in the
current task, then instead of launching a new instance of that
activity, all of the other activities on top of it will be closed and
this Intent will be delivered to the (now on top) old activity as a
new Intent.
For example, consider a task consisting of the activities: A, B, C, D.
If D calls startActivity() with an Intent that resolves to the
component of activity B, then C and D will be finished and B receive
the given Intent, resulting in the stack now being: A, B.
Use it like
Intent intent = new Intent(getApplicationContext(),
yourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
and also, take a look at this question:
Activity with Flag FLAG_ACTIVITY_CLEAR_TOP (android)
Edit : I thought you want to move to your home activity from D and want to remove all activities from stack
Your stack would be like homeactivity , A , B , C , D
so i gave you this solution as this shall remove all activities in stack on top of your home activity.
If you want to clear the the stack while going to D, for that you can use FLAG_ACTIVITY_TASK_ON_HOME or FLAG_ACTIVITY_CLEAR_TASK
But both of these for api level 11.
The correct answer interesting for me also, but I can offer a solution:
For example you start activity A from O: O->A->B->C->D.
On activity O you can put in android manifest android:launchMode="singleTop"
Then, when data are ok, you can start activity O with flag "FLAG_ACTIVITY_CLEAR_TOP" - it remove from stack A,B,C and will be called method onNewIntent (Intent intent) http://developer.android.com/reference/android/app/Activity.html#onNewIntent(android.content.Intent) in O, where you can start activity D.
You can start activities with startActivityForResult, and call setResult from for example activity D, in C activity you can listen activity result, and related of this result finish activity or not, or call setResalt from C activity ...
When you want to move D activity there you need to check your
conditions and if your condition is satisfied then you need to enter
into your Next activity(i.e., D) .In that case you need to use the
following code..
Intent intent = new Intent(this,D.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Suppose In on backpress you need to use finish(). to move back i.e., C
-> B -> A.
Try this piece of code with some modifications:
Intent intent = new Intent(this, D.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // To clean up all activities
startActivity(intent);
Try looking for Activity's public method startActivity(Intent i) and finish() here
In usage wise, it should look like this.
Intent i = new Intent(MainActivity.this, MainActivity.class);
startActivity(i);
finish();
Hope this helps :D

FLAG_ACTIVITY_CLEAR_TOP calls onCreate() instead of onResume()

So I have an abstract class extended through the entire app that overrides the back key to reorder Activity A to the front (With the flag).
So, it would be:
A > B > anywhere, and the back key should bring me back to A
I'm using the FLAG_ACTIVITY_CLEAR_TOP, but it is entirely refreshing A for some reason and I don't want that.
So: Flag_activity_clear_top is reloading the onCreate() rather than onResume(). What gives?
If you want the activity to just be brought to the top without restarting it set the launchMode of the activity to singleTop in the manifest. You will receive a call to onNewIntent when the activity is being brought to the top. onNewIntent is called before onResume. If you only want this behavior for the specific intent you can add the FLAG_ACTIVITY_SINGLE_TOP(in addition to FLAG_ACTIVITY_CLEAR_TOP) to the intent with the addFlags call instead of the manifest.
Intent intent = new Intent(CurrentActivity.this, ActivityNeedOnTop.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
CurrentActivity.this.finish();
From the API docs for FLAG_ACTIVITY_CLEAR_TOP
For example, consider a task consisting of the activities:
A, B, C, D. If D calls startActivity() with an Intent that
resolves to the component of activity B, then C and D
will be finished and B receive the given Intent,
resulting in the stack now being: A, B.
**The currently running instance of activity B in the above example
will either receive the new intent you are starting here in its
onNewIntent() method, or be itself finished and restarted with the new intent.**
So I think your activity is itself finished and restarted.

FLAG_ACTIVITY_CLEAR_TOP and android:launchMode="singleInstance"

I think I've just found a really strange bug... But it can just be somekind of feature that I never heard of.
On my application if I have any Activity on the AndroidManifest with android:launchMode="singleInstance" when you try to "clean" the stack to a certain point with the following code:
Intent intent = new Intent(this, Xpto.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
It goes to that activity. But when you press back, it returns to the previous.that should have been finished...
Example:
A -> B -> C
Then from C I call A with Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_CLEAR_TOP having A singleInstance on the Manifest. It goes to A but it only brings it to front. And does not finishes C and B.
Can somebody explain this behaviour?
The Xpto class I'm calling is at the time the root activity of the stack.
from reading this thread:
http://groups.google.com/group/android-developers/browse_thread/thread/5eb400434e2c35f4
it seems that:
"The currently running instance of activity B in the above example will
either receive the new intent you are starting here in its onNewIntent()
method, or be itself finished and restarted with the new intent. If it
has declared its launch mode to be "multiple" (the default) and you have
not set FLAG_ACTIVITY_SINGLE_TOP in the same intent, then it will be
finished and re-created; for all other launch modes or if
FLAG_ACTIVITY_SINGLE_TOP is set then this Intent will be delivered to
the current instance's onNewIntent(). "
which means that you need to set your launchMode to multiple instance, and use only FLAG_ACTIVITY_CLEAR_TOP.
Intent intent = new Intent(this, Xpto.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
In the scenario you described, activity's B and C are not finished when you start activity A (which is the root activity). The documentation describes that with launch mode of singleInstance and the flag FLAG_ACTIVITY_SINGLE_TOP set, activities B and C will NOT be finished. If you want to have activities B and C finished, then you must set the launch mode to multiple instance and NOT set the flag FLAG_ACTIVITY_SINGLE_TOP.

Categories

Resources