Search code examples
androidandroid-intentandroid-activityback-stack

Backstack and Standard login practices in android app


What is the standard way of achieving something like below?

The diagram below is self-explanatory

In the SplashActivity, I check if there is an user logged in using the database, if so get the details and go straight to MainActivity

if (App.getAccountData().isSomeoneSignedIn()) {
    // then skip everything and go to Home Screen, dont need to send any user info, home screen picks up directly from appData
    Log.i("XXX", "Found an User, email = " + App.getAccountData().getEmail() + " .Going straight to home");
    Intent intent = new Intent(this, MainActivity_.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(intent);
    finish();
}

When I go from Splash --> Signin, I want to keep Splash in backstack, however, when I go from Signin -->Main, I want to remove everything and keep just Main in the stack, so that pressing the back button brings user to Android Home.

Similary, in the Signup flow, I want to keep the backstack upto ExtraInfo2, but in ExtraInfo2 -->Main, I want to remove the entire backstack so that pressing the Back button brings user (who is logged in) to Android Home.

How can I achieve this?

    +----------SplashActivity-----+                                     
    |                             |                                     
    |  Sign In            Sign Up <----------------------+              
    |   +                         |                      |              
    +---------------------------+-+                      |              
        |                       |                        |              
        |                       |                        |              
        |                +------+------------+           |              
   +----+-----+          |                   |           |              
   |          |          | RegisterEmailPwdActivity      |              
   | Get email, pwd      |                   |           |              
   |          |          |                   |Back does usual           
   | SignInActivity      |                   |           |              
   |          |          |                   |           |              
   |          |          +-----+-------------+           |              
   |          |                |                         |              
   |          |           +----v----------+---+          |              
   +--+-------+           | ExtraInfo1Activity|          |              
      |                   |                   | Back does usual         
      |                   |                   |          |              
      |                   |                   |          |              
      |                   +----+--------------+          |              
      |                        |                         |              
      |                   +----v----------+---+          |              
      |                   | ExtraInfo2Activity|Back disabled            
      |                   |                   |          |              
      |                   +----+--------------+          |              
      |                        |                         |              
Should clear full stack here   |                         |              
   +---------------------------v-----------+             |              
   |                                       |             |              
   |                                       |             |              
   |              Main Activity        Logout------------+              
   |          Back should minimize         |      Logout takes to splash
   +---------------------------------------+                            

Solution

  • When I go from Splash --> Signin, I want to keep Splash in backstack, however, when I go from Signin -->Main, I want to remove everything and keep just Main in the stack, so that pressing the back button brings user to Android Home.

    When you transition from SignInActivity to MainActivity, you can set intent flags to achieve your desired outcome. Here is an example method that sets the FLAG_ACTIVITY_CLEAR_TASK and FLAG_ACTIVITY_NEW_TASK.

        private void startMainActivity() {
           Intent intent = new Intent(mContext, MainActivity.class);
           intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
           startActivity(intent);
        }
    

    Similary, in the Signup flow, I want to keep the backstack upto ExtraInfo2, but in ExtraInfo2 -->Main, I want to remove the entire backstack so that pressing the Back button brings user (who is logged in) to Android Home.

    This would work in a similar way. When you transition from ExtraInfoActivity1 to ExtraInfoActivity2, set the flags as they were set in the example above.

    Do the same when transitioning from ExtraInfoActivity2 to MainActivity. Then when back is pressed from MainActivity the user will be taken to the homescreen.

    Another tip is to use a feature of the adb shell to inspect which activities are currently in the backstack (and you can see which task they're in as well). To do this, connect the device to your computer, run the app, open a terminal then get into adb shell and run the command dumpsys activity. A lot of text will be generated but some of it will look like the following:

      Stack #1:
    Task id #193
      TaskRecord{432f8570 #193 A=com.activitybackstacktester U=0 sz=1}
      Intent { flg=0x10008000 cmp=com.activitybackstacktester/.MainActivity }
        Hist #0: ActivityRecord{42f2a090 u0 com.activitybackstacktester/.MainActivity t193}
          Intent { flg=0x10008000 cmp=com.activitybackstacktester/.MainActivity }
          ProcessRecord{431267b8 32667:com.activitybackstacktester/u0a156}
    Running activities (most recent first):
      TaskRecord{432f8570 #193 A=com.activitybackstacktester U=0 sz=1}
        Run #0: ActivityRecord{42f2a090 u0 com.activitybackstacktester/.MainActivity t193}
    

    This output tells you that in task stack #1, there is one activity on the stack and its name is MainActivity. If you run this command when the SignInActivity is in the foreground, you should see that the task has LoginActivity and SignInActivity in the stack. This is a great way of verifying that the backstack contains only the activities that you intend it to.