what is the better way to check if the activity is still in the stack in order to call it back ?
Intent i = new Intent(getApplicationContext(),MyClass.class);
startActivity(i);
Using activity. isFinishing() is the right one solution. it return true if activity is finished so before creating dialog check for the condition.
If no task for the app exists (because it hasn't been used recently), a new task is created, and the app's “main” activity is opened as the stack's root activity. When the current activity switches to a new one, the new activity is pushed to the top of the stack and takes control of the attention.
Activities in the stack are never rearranged, only pushed and popped from the stack—pushed onto the stack when started by the current activity and popped off when the user leaves it using the Back button or gesture. As such, the back stack operates as a last in, first out object structure.
I am surprised how unpopular this (kind of) question(s) is.
Let me start from the solution first:
Since ActivityManager.getRunningTasks
is deprecated since API 21,
We have to find another way to get what activities are in the backstack. And I realized that we can actually implement our own "stack"!
I declared an ArrayList in MyOwnApplication:
private ArrayList<Class> runningActivities = new ArrayList<>();
And added public methods to access and modify this list:
public void addThisActivityToRunningActivityies (Class cls) {
if (!runningActivities.contains(cls)) runningActivities.add(cls);
}
public void removeThisActivityFromRunningActivities (Class cls) {
if (runningActivities.contains(cls)) runningActivities.remove(cls);
}
public boolean isActivityInBackStack (Class cls) {
return runningActivities.contains(cls);
}
In a BaseActivity
where all activities extend it:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((MyOwnApplication)getApplication()).addThisActivityToRunningActivityies(this.getClass());
}
@Override
protected void onDestroy() {
super.onDestroy();
((MyOwnApplication)getApplication()).removeThisActivityFromRunningActivities(this.getClass());
}
And then you can easily use isActivityInBackStack
to check.
WHY IS THIS NECESSARY?
Yes, of course, most cases can be done by using Intent Flags and proper navigation.
But there is such a use case, which I think should be common, that I don't find a solution simply by using intent flags.
Suppose I have an application that has a navigation drawer in almost every activity.
I navigate from MainActivity
to ActivityA
, and then created ChildActivityB
from ActivityA
. Please note that ActivityA
is not parent of ChildActivityB
since ChildActivityB
can be opened from other activities such as notification.
Note that, ChildActivityB
also has a drawer. I can navigate to ActivityA
through drawer, instead of pressing up or back button. Now, imagine you loop through such process: Activity A -> ChildActivity B -> Drawer -> Activity A -> ChildActivityB -> Drawer -> Activity A .....
Infinite activities will be created in the backstack.
To fix such behavior, we need to use Intent Flags:
(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP);
So far so good.
However, I have custom activity transition animations by using overridePendingTransition()
. I noticed that if I put the above intent flags together with overridePendingTransition()
, there will be a glitch in animation because the activity is destroyed at the middle of the animation, due to the flag Intent.FLAG_ACTIVITY_CLEAR_TOP
.
Now, if I am able to detect whether ActivityA
is in the backstack or not, the behavior will be perfect:
private void navigateToDrawerItems(Class cls) {
drawerLayout.closeDrawer(GravityCompat.END);
Intent intent = new Intent(this, cls);
if (((MyOwnApplication)getApplication()).isActivityInBackStack(cls)) {
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
} else {
startActivity(intent);
overridePendingTransition(R.anim.slide_right_in, R.anim.slide_left_out);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With