0

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?

Pikaling
  • 8,282
  • 3
  • 27
  • 44
  • Please post the full exception, and what you are doing when loading the Welcome activity (onStart()). Are you loading values? – Jack Aug 13 '11 at 17:50
  • The full exception isn't interesting - it's just a NPE for the database connection, which obviously hasn't been restarted as it's not starting the correct Activity. The Welcome Activity's onCreate method redirects to another Activity depending on the SharedPreferences, but none of the LogCat statements in the onCreate method are appearing, so it's not starting. I've added that method to my question so you can see – Pikaling Aug 13 '11 at 18:08

2 Answers2

0

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()
NickT
  • 23,844
  • 11
  • 78
  • 121
  • As you can see from the onCreate method of Welcome, it **does** call finish(). And when I start the app from home, it **doesn't** call onResume() of Welcome (I've tested using LogCat). It just tries to resume the Activity that was running when it was closed. I want the app to start fresh. I think I'm probably missing an Intent flag, but I can't work out which one – Pikaling Aug 13 '11 at 20:00
0

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?

Community
  • 1
  • 1
Pikaling
  • 8,282
  • 3
  • 27
  • 44