开发者

Application starts wrong Activity and Force Closes

My appliaction features a menu with a logout button that allows you to log out from any Activity. This has been working fine. It used to log out to the app's Welcome screen, but I recently changed it to log out to the device's home screen. Now, when I log out and open the app, it force closes. On the second attempt to start the app, it will start correctly.

On the first attempt, it seems to try to load the Activity that was running when the user logged out, despite LogCat showing it starting the correct Intent:

08-13 17:14:18.983: INFO/ActivityManager(59): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=uk.ac.ic.doc.vmw10.wherewolf/.activities.Welcome }
08-13 17:14:19.053: VERBOSE/WWA(8611): setting up
08-13 17:14:19.064: DEBUG/AndroidRuntime(8611): Shutting down VM
08-13 17:14:19.064: WARN/dalvikvm(8611): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
08-13 17:14:19.083: ERROR/AndroidRuntime(8611): FATAL EXCEPTION: main
08-13 17:14:19.083: ERROR/AndroidRuntime(8611): java.lang.RuntimeException: Unable to resume activity {uk.ac.ic.doc.vmw10.wherewolf/uk.ac.ic.doc.vmw10.wherewolf.activities.Tabs}: java.lang.NullPointerException

Immediately after it starts the correct Intent, a verbose message is output from the wrong activity, and then the app crashes due to a NullPointerException. Why is it not starting the Welcome activity, as the Intent claims it is?

Here's the logout function:

public void logout() {
    SharedPreferences.Editor prefEditor = preferences.edit();
    prefEditor.remove(PASSWORD);
    prefEditor.remove(FIRST_NAME);
    prefEditor.remove(LAST_NAME);
    prefEditor.remove(EMAIL_ADDRESS);
    prefEditor.remove(DATE);    
    prefEditor.remove(PICTURE); 
    prefEditor.remove(TOKEN);   
    prefEditor.commit();

    final Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    syncTask.cancel(true);
    dbHelper.close();
    dbHelper=null;
    firstRun = true;
    startActivity(intent); 
}

Edit: Here's the onCreate method for the Welcome Activity:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    Log.v(TAG, "preferences: "+preferences.getAll());
    if(preferences.contains(WhereWolfActivity.EMAIL_ADDRESS)) {
        Log.v(TAG, "user preferences saved from previous session: "+preferences.getAll().toString());
        intent = new Intent(getApplicationContext(), Tabs.class);
        startActivity(intent);
        finish();
    }
    else if(preferences.contains(WhereWolfActivity.USER_ID) &! preferences.contains(WhereWolfActivity.EMAIL_ADDRESS)) {
        Log.v(TAG, "known user returning to log in");
        intent = new Intent(getApplicationContext(), Login.class);
        startActivity(intent);
        finish();
    }
    else {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.welcome);
    }  
}

Edit:

Not only is it starting the wrong Activity, it is not calling the onCreate method of that Activity, but it does call onStart. Ths suggests that it is trying to pick up where it left off, even though that's not what I want it to do! How can I persuade it not to do this?

Edit:

As all my 'logged in' Activity's have a superclass they inherit from, I added a bit to that superclass's onStart() method that would check if the user was logged in, and if not it would start the Welcome Activity:

public void onStart () {
    super.onStart();
    if(!preferences.contains(EMAIL_ADDRESS)) {
        Log.v(TAG, "not logged in");
        Intent intent = new Intent(getApplicationContext(), Welcome.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        finish();
    }

This hasn't worked. Here's the LogCat output:

08-13 20:41:10.223: INFO/ActivityManager(59): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=uk.ac.ic.doc.vmw10.wherewolf/.activities.Welcome }
08-13 20:41:10.254: VERBOSE/WWA(2171): not logged in
08-13 20:41:10.263: INFO/ActivityManager(59): Starting activity: Intent { flg=0x4000000 cmp=uk.ac.ic.doc.vmw10.wherewolf/.activities.Welcome }
08-13 20:41:10.273: VERBOSE/WWA(2171): setting up
08-13 20:41:10.320: DEBUG/AndroidRuntime(2171): Shutting down VM
08-13 20:41:10.320: WARN/dalvikvm(2171): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
08-13 20:41:10.343: ERROR/AndroidRuntime(2171): FATAL EXCEPTION: main
08-13 20:41:10.343: ERROR/AndroidRuntime(2171): java.lang.RuntimeException: Unable to resume activity {uk.ac.ic.doc.vmw10.wherewolf/uk.ac.ic.doc.vmw10.wherewolf.activities.Tabs}: java.lang.NullPointerException

The superclass has the tag WWA. As you can see, it says开发者_如何学运维 'not logged in', then starts the Welcome Activity, and then carries on anyway. Any ideas?


If you are logging out back to the home screen it suggests to me that you only want to see the welcome screen once, when you start the app from home?

If that's right, then in the welcome onCreate(), call finish() before starting tabs or login activities. As it stands you've gone home->welcome->tabs_or_login->logout->start app again

  • However welcome activity is still in memory and only paused. Thus onResume() will run but not onCreate()


I solved the problem by adding this to the onPause() method of my superclass:

if(!preferences.contains(EMAIL_ADDRESS)) { // this means the user has logged out
    finish();
}

Now, when the user logs out, all Activity's are finished properly. I also changed it back to logging out to the log in screen rather than logging out to the device's home screen after reading this post: Is quitting an application frowned upon?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜