Search code examples
androidlaunch

How to remove specific activity from the stack


Lets put we 3 activates that may follow the stack A->B->C

How can I close A and keep B->C, but only if B opens C?

C is not always opened, but if it gets opened only then A should be removed, leaving the stack as B->C. Otherwise will remain as A->B.

I don't see the possibility of using finish() in A, as it should be closed from B when opening C.

By the way A is a single instance with its own affinity.


Solution

  • Write an abstract BaseActivity class and implement a LocalBroadcastManager in it and register a BroadcastReceiver. Note that we have also introduced an abstract onFinishReceived method.

    public abstract class BaseActivity extends AppCompatActivity {
    
      private LocalBroadcastManager mLBM;
      private final BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
          onFinishReceived(intent.getStringExtra("activity"));
        }
      }
    
      protected void onCreate(@Nullable Bundle savedInstanceState) {
        ...
        mLBM = LocalBroadcastManager.getInstance(this);
        IntentFilter filter = new IntentFilter();
        filter.addAction(...);
        mLBM.registerReceiver(receiver, filter);
      }
    
      protected void onDestroy() {
        mLBM.unregisterReceiver(receiver);
        mLBM = null;
      }
    
      abstract void onFinishReceived(String activity);
    }
    

    Then, extend all A, B and C Activities from the BaseActivity and override the onFinishReceived() method.

    public class A extends BaseActivity {
    
      void onFinishReceived(String activity) {
        if (activity.equals("A") { // or "B" or "C"
            finish();
          }
        }
      }
    }
    

    Now, whenever you want to finish a specific activity use,

    LocalBroadcastManager.getInstance(context)
        .sendBroadcast(new Intent()
            .setAction(...)
            .putExtra("activity", "A") // or "B" or "C"
        );
    

    LocalBroadcastManager is now deprecated. It's better if you can use something like RxJava. The idea is to use an asynchronous and event-based mechanism rather than going for a simple ugly solution like storing the Activity in a static variable.