I am writing a application where I am dealing with 4 activities, let\'s say A, B, C & D. Activity A invokes B, B invokes C, C invokes D. On each of the activity, I have
The only problem i see using android:launchMode="singleTask"
is whenever you minimize app and start app by pressing app icon again then app start from scratch and doesn't acquire its state. so i have opted to use
intent.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP );
which will keep only one instance and clear all activities on top of that.
Intent intent = new Intent( context, MyActivity.class );
intent.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP );
current_activity.startActivity( intent );
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(D.this, A.class));
}
});
Declare A in your manifest with the android:launchMode="singleTask"
. This way, when you call startActivity()
from your other activies, and A is already running, it will just bring it to the front. Otherwise it'll launch a new instance.
I'm using https://github.com/greenrobot/EventBus fo this. In root activity you must subscribe for event
EventBus.getDefault().register(this);
Then you must define event callback
public void onEvent(LogoutEvent event) {
// your implementation
logout();
}
and the logout button listener must have code like this:
finish(); // you must finish previous activity
EventBus.getDefault().post(new LogoutEvent());
That's all
First of all I can't believe Android does not have an easy equivalent of iOS poptorootviewcontroller.
The problem with using an intent and startactivity is that as far as I know it will recreate the root activity which is a problem if for example it is using an asynchronous network request to load data and layout the interface. This may have unpleasant visual effects.
Here is a creative solution I have used in my friendfolder project:
Create a global boolean: public boolean myBool = true;
Do this in MyApplication class and register the class in the manifest:
<application
android:name=".MyApplication"
Activity A is the root, do this in onResume:
if(((MyApplication) this.getApplication()).myBool == false) {
if(isTaskRoot()) {
((MyApplication) this.getApplication()).myBool = true;
} else {
finish();
}
}
In every activity that will go on top of Activity A put this code in:
@Override
public void onResume() {
super.onResume();
if(((MyApplication) this.getApplication()).myBool == false) {
finish();
}
}
@Override
public boolean onSupportNavigateUp(){
((MyApplication) this.getApplication()).myBool = false;
finish();
return true;
}
You can even put this in activity A as well if you are stacking other instances of A on top of the root A. onSupportNavigateUp is for the up button. Substitute this method for another if using your own button.
Now when you have some activities stacked on top of A and you press the up button the top activity will finish and the onresume will be called by the system on the activity below in the stack and it will finish. This will work in a chain all the way back to the root A.
Kotlin
fun Context.popToRoot()
{
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
startActivity(intent)
}
Change MainActivity to your main activiy.
In any activity just call:
this.popToRoot()
This works for me
Intent intent = new Intent(D.this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
In the manifest:
android:name=".A"
android:launchMode="singleTask"