javaandroidandroid-lifecycleback-stack

Activity still staying over previous activity in Android Strange Behaviour


The situation is I call an activity from my RouteActivity by:

arrived.observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(Boolean aBoolean) {
                if(aBoolean==true){
                    Intent intent = new Intent(MyApplication.getAppContext(), RouteCompleteActivity.class);
                    startActivity(intent);
                    overridePendingTransition(R.anim.slide_up, R.anim.do_nothing);
                    finish();
                }
            }
        });

That is fine then when I close the activity by calling:

Intent navIntent = new Intent(MyApplication.getAppContext(), NavigationStartActivity.class);
                navIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(navIntent);
                finish();

This takes me back to my main NavigationStartActivity, then when I again choose to go back to my RouteActivity the original, the RouteCompleteActivity is still over the top of it? so instead of RouteActivity I get RouteCompleteActivity then if I press back it goes to the RouteActivity?? as if it has remembered some backstack? can anyone explain this?


Solution

  • I assume that you're using a LiveData from a viewModel or repository which keeps its value. The case is like this: arrived has a true value and onChanged will be called. The next time RouteActivity observes arrived, onChanged will be called again because it already has a value and another startAcrivity will be called. A simple solution would be using SingleLiveEvent instead which was created by google long time ago link

    public class SingleLiveEvent<T> extends MutableLiveData<T> {
    
    private static final String TAG = "SingleLiveEvent";
    
    private final AtomicBoolean mPending = new AtomicBoolean(false);
    
    @MainThread
    public void observe(LifecycleOwner owner, final Observer<T> observer) {
    
        if (hasActiveObservers()) {
            Log.w(TAG, "Multiple observers registered but only one will be notified of changes.");
        }
    
        // Observe the internal MutableLiveData
        super.observe(owner, new Observer<T>() {
            @Override
            public void onChanged(@Nullable T t) {
                if (mPending.compareAndSet(true, false)) {
                    observer.onChanged(t);
                }
            }
        });
    }
    
    @MainThread
    public void setValue(@Nullable T t) {
        mPending.set(true);
        super.setValue(t);
    }
    
    /**
     * Used for cases where T is Void, to make calls cleaner.
     */
    @MainThread
    public void call() {
        setValue(null);
    }
    }
    

    It simply calls onChange when a new value is set. I also recommend to take a look at this article which describes it deeper