简体   繁体   中英

Android Activity Stack is not working as stated in the docs - last activity in task stack not shown

According to Android docs:

http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html

"When the user leaves a task by pressing the Home button, the current activity is stopped and its task goes into the background. The system retains the state of every activity in the task. If the user later resumes the task by selecting the launcher icon that began the task, the task comes to the foreground and resumes the activity at the top of the stack."

If I understand this correctly, this means:

  1. Activity A as MAIN Activity.
  2. Activity B that gets started in A, through "startActivity" - common, plain intent instance.
  3. I open app for first time, A gets loaded.
  4. I click on button in A and B is openend.
  5. I press home button.
  6. I open app again, for 2nd time, and B is expected to be shown

...right? I suppose this is the correct behavior to expect...

However, I am not seeing this in my app.

If I hit "Home button" and then resume my app, by pressing the launcher icon, it will start with the main activity - not the one at the top or latest one.

I am coding on a Samsung Galaxy Tab Android 2.2.1 - I have the most common options in the Android manifest - thing is that I handle like 10 different activities with different intent extras - and a Dispatcher class approach - or save each activity state - sounds quite demanding.

I am using Eclipse IDE with ADT version 12; and I found something very interesting:

When I run the app from the Eclipse IDE, with my device connected, I don't see this behavior. The app behaves as stated in the docs. In fact, I saw this only after I deployed my apk at the Google Play app repository; and downloaded it to test.

My question is, has anybody found the real reason why is this happening? Is the documentation wrong? or missing something? Is this a bug on Android?

Another research I have done is:

When I try my app, downloaded from the google play, as APK, if I enter my app for the 2nd time, I get the "main" activity instead of the last one openend. I press home. After pressing home, I enter application management settings for android, locate my app and click on "force stop". After doing this, the app behaves as stated in the docs.

Somebody help! :)

This is a bug in android's platform:

http://code.google.com/p/android/issues/detail?id=2373

The workaround is, to place this in the onCreate method of your main Activity:

if (!isTaskRoot())
{
    final Intent intent = getIntent();
    final String intentAction = intent.getAction(); 
    if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && intentAction != null && intentAction.equals(Intent.ACTION_MAIN))
    {
        Log.w(LOG_TAG, "Main Activity is not the root.  Finishing Main Activity instead of launching.");
        finish();
        return;       
    }
}

as extracted from:

How to prevent multiple instances of an activity when it is launched with different intents

...spent 3 days looking out for this.

I'm just going to explain why it fails, and how to reproduce this bug programmatically so you can incorporate this in your test suite:

  1. When you launch an app through Eclipse or Market App, it launches with intent flags: FLAG_ACTIVITY_NEW_TASK.

  2. When launching through the launcher (home), it uses flags: FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_BROUGHT_TO_FRONT | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED, and uses action " MAIN " and category " LAUNCHER ".

If you would like to reproduce this in a test case, use these steps:

adb shell am start -f 0x10000000 -n com.testfairy.tests.regression.taskroot/.MainActivity 

Then do whatever is needed to get to the other activity. For my purposes, I just placed a button that starts another activity. Then, go back to the launcher (home) with:

adb shell am start -W -c android.intent.category.HOME -a android.intent.action.MAIN

And simulate launching it via the launcher with this:

adb shell am start -a "android.intent.action.MAIN" -c "android.intent.category.LAUNCHER" -f 0x10600000 -n com.testfairy.tests.regression.taskroot/.MainActivity

If you haven't incorporated the isTaskRoot() workaround, this will reproduce the problem. We use this in our automatic testing to make sure this bug never occurs again.

Hope this helps!

文档是正确的,我能想到的唯一可能的问题是导致这是你正在测试的设备,如果它在模拟器(Android股票)上按预期工作,它至少应该在Androids的90%上工作,它的制造商故障,我相信不是Android。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM