Unwanted behavior with back button on a login scre

2019-06-03 23:42发布

问题:

So I'm building an app, and it has a splash/login screen with a facebook login button. After the user logs in, and a user object with info returns, I want to insert some data into the database (not in the code yet, but doesn't matter), and then open the MainActivity activity.

What happens is that on first launch, everything works correctly: If the user is already logged in (=there is an active session), the MainActivity activity is launched. If the user is not logged in, a login button shows asking the user to log in, and again opens the MainActivity activity on success.

If a user hits the back button from MainActivity, a white screen shows, and it stays that way. If the back button is pressed again, the app closes, and when the app is resumed (from the "Recent Apps" window for example), the white screen shows for another 1-2 seconds, and then proceeds to MainActivity.

I think it happens because it tries to go back to the SplashActivity but since I finish() it, it can't... although, I'm not so sure since I tried to clean the backstack using Intent.FLAG_ACTIVITY_CLEAR_TOP and Intent.FLAG_ACTIVITY_NEW_TASK...

What could cause this behavior? How could I fix it?

Extra Info:
- SplashActivity is set to launch as the launcher of the app using intent-filter in the app's manifest:<intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
- Tested on HTC Sensation XE /w Android 4.1

Here's some code (SplashActivity):

public class SplashActivity extends Activity {
    private UiLifecycleHelper uiHelper;
    private Session.StatusCallback callback =
        new Session.StatusCallback() {
            @Override
            public void call(Session session, SessionState state, Exception exception) {
                onSessionStateChange(session, state, exception);    
            }
      };
    private ArrayList<String> permissions;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash);

        uiHelper = new UiLifecycleHelper(this, callback);
        uiHelper.onCreate(savedInstanceState);

        permissions = new ArrayList<String>();
        permissions.add("email");
        permissions.add("user_birthday");

        Session session = Session.getActiveSession();
        if(session != null && session.isOpened()) {
            if(!session.getPermissions().contains(permissions)) {
                session.requestNewReadPermissions(new Session.NewPermissionsRequest(SplashActivity.this, permissions));
            }
        } else {
            LoginButton authButton = (LoginButton) findViewById(R.id.login_button);
            authButton.setReadPermissions(permissions);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        uiHelper.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        uiHelper.onPause();
    }

    private void onSessionStateChange(Session session, SessionState state, Exception exception) {
        if(session != null && state.isOpened()) {
                Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
                    @Override
                    public void onCompleted(GraphUser user, Response response) {
                        if (user != null) {
                                                    //no code here yet
                        }
                    }
                });
                Intent intent = new Intent(SplashActivity.this, MainActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
                finish();
    }
}

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        uiHelper.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        uiHelper.onSaveInstanceState(outState);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        uiHelper.onDestroy();
    }

}

回答1:

It sounds like you don't want the splash activity on your stack. If so, you could do something like this to launch you main activity.

  Thread nohistory = new Thread () {
    public void run () {
        try {
            Intent i = new Intent(Splash.this, ActivitySplash.class);
            i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(i);
            finish();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
};
nohistory.start();

hope this helps.



回答2:

Found the solution!

Apparently it was this if line:
if(!session.getPermissions().contains(permissions))

What it did is check whether my permissions ARRAY (as an object) was inside the current session's permissions array, and if it doesn't (which is always, basically), fire session.requestNewReadPermissions(new Session.NewPermissionsRequest(SplashActivity.this, permissions));.

All I did was simply change it to one of my permissions array strings:
if(!session.getPermissions().contains("email"))

And now it works! No white screen anymore. I am not sure why it caused such behavior though... maybe because the activity could not finish() properly... no idea, but it works.

How I found out:
Simply tucked Log.i() inside of the if and noticed that it always fires even though it shouldn't.