tags:

views:

161

answers:

2

Pressing the back button causes onPause to be called, and the app stays paused until it is re-launched by clicking on the icon, at which point, onDestroy gets called, and the main activity continues to shut down.

Simple class to demonstrate. Note, as far as I can tell, this only happens on the Nexus One. I can't reproduce it in the emulator or on my Droid.

package com.vimtips.testshutdown;

import android.app.ActivityGroup;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;

public class MainActivity extends ActivityGroup {
    private static final String TAG = "MainActivity";
    private int counter = 3;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK) {

            if(counter-- > 0) return true;
        }

        return super.onKeyDown(keyCode, event);
    }

    @Override
    public void onPause() {
            super.onPause();
            Log.d(TAG, "onPause called");
    }

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

        if(isFinishing()) {
            Log.d(TAG, "Shutting down");
        }
    }
}

And here's the log:

I/ActivityManager(  132): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10100000 cmp=com.vimtips.testshutdown/.MainActivity }
I/ActivityManager(  132): Displayed activity com.vimtips.testshutdown/.MainActivity: 305 ms (total 305 ms)
D/MainActivity( 1393): onPause called
I/ActivityManager(  132): Displayed activity com.vimtips.testshutdown/.MainActivity: 302 ms (total 302 ms)
D/MainActivity( 1393): Shutting down

This doesn't appear to happen on a normal Activity, just an Activity group, though looking at Android's sourcecode, I can't figure out why. It's causing some serious problems with my app.

Anyone know why this would happen?

+1  A: 

This is dependent on the launchMode of the app and the intent flags. Currently, on emulator any activity is started with the following flags :

  • Intent.FLAG_ACTIVITY_NEW_TASK
  • Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

And if there aren't any flags specified then it will restart the activity, which is happening in your case.

Karan
Where do I add/modify these flags to match the Nexus One if it's the main activity? I assume somewhere in the manifest? What's happening on the Droid?
synic
You can specify the launchMode for any activity in AndroidManifest. Try using singleTop as launchMode, this will not call the onResume, rather it will call the onNewIntent() method in the activity. Btw can you please check for the Intent flags that you are getting currently in onCreate() and in onResume() ?
Karan
I'm already passing singleTask.. which makes it seem like this situation is impossible. When someone launches the activity after it's been closed, a new one is created before the old one finishes being destroyed, meaning that two instances are actually alive for a moment. Try it yourself, with the class I provided as the only activity and set as singleTask, on the Nexus One if you have it. It doesn't happen on a G1, Droid, or the emulator.
synic
Try the dumpsys command on adb shell, you will get the tast stack and activity Z-order stack. If you are using the singleTask, then you should only see a single entry of the activity in that task stack.Btw singleTask will restrict multiple instances of the same activity within a task, that is why the other activity gets destroyed when starting the new one.Try the standard and singleTop launch mode. I don't have the devices otherwise I would have tried this.
Karan
I'll have to give it a try when my roommate gets home. He's the one with the Nexus One. I really don't think this is what's happening. Why doesn't the activity finish when the user presses back in the first place? It shouldn't matter what intents are fired when the user returns to the app.
synic
Android won't finish the activity when you click on back button, it will remain in activity stack. If there is low memory issue then it will delete the activity from stack. Try the same test with all the functions overwritten( onResume(), onFinish() ), and see what happens.
Karan
I have. On the Droid and the emulator, it does finish the activity. I've even overridden the onKeyPress and finished() explicitly on the Nexus, however, it still just pauses the activity until the app is relaunched.
synic