Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to go back to a specific activity if activities are implemented by same class

To implement the up navigation, I would like to go back to a specific activity on the history stack. If the activities on the stack are implemented by different classes, it works like this (assuming I have activities A, B and C on the stack and want to go back to activity A:

protected void onUpPressed() {
    Intent intent = new Intent(this, A.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                  | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    startActivity(intent);
    finish();
}

Android will pop activities off the stack until the activity specified by the intent is the top most (activity implemented by class A in this case).

However, my app has several activities on the stack implemented by the same class. That's because they display the same kind of data but for different objects. They were launched with an intent that specified both the class implementing the activity and the object to display (either in the extras bundle or in the data property).

Now I'm looking for code to again pop several activities off the history stack until the matching activity the top most. If I extend the above code and additionally set the extras bundle or the data property, it doesn't work. Android always matches the first activity implemented by the specified class and doesn't go back far enough. The extras bundle and the data property are ignored.

protected void onUpPressed() {
    Intent intent = new Intent(this, A.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                  | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    intent.setData(Uri.parse("myapp:" + rootId));
    startActivity(intent);
    finish();
}

So how can I achieve to go back to a specific activity? What intent fields does Android compare to determine if it has found the desired activity?

like image 825
Codo Avatar asked May 08 '14 18:05

Codo


People also ask

How do I go back to previous activity?

In the second activity, the back button at the top left can be used to go back to the previous activity.

What code would you use to go back to a previous activity?

In that case you can just call the finishActivity() function from your code and it'll take you back to the previous activity.

When moving from one activity to another activity which method is used to return data back to its parent?

The setResult method takes an int result value and an Intent that is passed back to the calling Activity.

What is used to navigate between activities?

Intents: Navigating between Activities (Amongst Other Things). We mentioned earlier that navigation between activities is managed by Intents. An Intent is a type of message that applications broadcast through the Android OS to interested parties on the phone.


2 Answers

As you described, you have one Activity that show different content based on the starting Intent. Well, why not Fragments?

I don't know the details of your applications architecture, but is should be easy to refactor that Activity to a Fragment. There could be a FragmentActivity that wraps all the Fragments which responsible for showing the content. This way you would have much more freedome to handle the activity's stack of fragments.

Steps summarized:

  • Convert your existing Activity (that show the content) to a Fragment.
  • Make a FragmentActivity (that will manage the Fragments).
  • Make the FragmentActivity "singleInstance", so it will cache all the "startActivity" requests, where you have the opportunity to add a new Fragment representing the new content to show.

You could add fragments this way:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    // ContentFragment is the Fragment that you made from your Activity.
    // Here you can pass the intent that stores the object to show also,
    // so the parsing of the intent would be the same.
    ContentFragment fragment = ContentFragment.newInstance(intent);

    getFragmentManager()
    .beginTransaction()
    .add(fragment, null)
    .addToBackStack("id here that will be used at pop")
    .commit();
}

And you can pop to a specific id this way:

getFragmentManager().popBackStack("id here", 0);

This solution has a side-effect. The fragments will stick together, so you cannot insert any other Activity between them. This is trivial, but worth mentioning since differs from your current implementation.

I also assumed that you are familiar with how "singleInstance" and Fragments work. Fell free to ask if something is not clear.

like image 189
kupsef Avatar answered Oct 05 '22 23:10

kupsef


To implement FLAG_ACTIVITY_CLEAR_TOP, Android searches through your task's activity stack (from top to bottom) using the following test:

                if (r.realActivity.equals(newR.realActivity)) {

Your problem is that realActivity is a ComponentName (so the above comparison locates the topmost activity in the stack that matches on package and class name): no further test is performed against the intent, so it is impossible to be any more specific about which of that component's activities you wish to target.

Therefore:

  1. So how can I achieve to go back to a specific activity?

    There is no native means of accomplishing this. Your best bet is probably to manually implement a form of bubbling as suggested by @VM4.

  2. What intent fields does Android compare to determine if it has found the desired activity?

    Only the component name.

like image 29
eggyal Avatar answered Oct 06 '22 01:10

eggyal