我已经根据您提供的代码创建了一个项目,并且能够在我自己的 Nexus 7 上重新创建您的问题。虽然我没有为您提供具体的学术答案,但我最好的解释如下:
1)MainActivity启动
2) 单击按钮。 AffinityTestActivity 在新任务中启动。
3) 单击按钮。 AffinityTestActivity 完成。
4) MainActivity 在旧任务中恢复。
5) 在MainActivity 的onResume 中,在同一任务中调用HelloActivity 的意图。
6)神秘的部分是我经过一番修改后的理论:将旧任务带到前台的某些部分在其 onResume 调用期间继续与旧任务的根 MainActivity 进行交互。这种交互会导致 HelloActivity 的 onPause 方法被触发(可能不是操作系统开发人员想要的)。虽然这不是最令人满意的答案(鉴于我在操作系统级调度代码和计时问题方面的经验有限),但我的实验指出了一些类似的内容。我对这种干扰的第一个线索是 logcat 中经常出现的错误:
06-24 11:06:28.015 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.MainActivity@64e05830 onPause
06-24 11:06:28.055 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.AffinityTestActivity@64e22fc0 onCreate
06-24 11:06:28.075 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.AffinityTestActivity@64e22fc0 onResume
06-24 11:06:28.175 665-685/? I/ActivityManager﹕ Displayed com.stackoverflow/.AffinityTestActivity: +163ms
06-24 11:06:29.997 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.AffinityTestActivity$1@64e24bf8 finishes
06-24 11:06:30.007 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.AffinityTestActivity@64e22fc0 onPause
06-24 11:06:30.027 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.MainActivity@64e05830 onResume
06-24 11:06:30.027 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.MainActivity@64e05830 starts HelloActivity
06-24 11:06:30.027 665-6346/? I/ActivityManager﹕ START u0 {cmp=com.stackoverflow/.HelloActivity} from pid 27200
06-24 11:06:30.117 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.HelloActivity@64e33b18 onCreate
06-24 11:06:30.127 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.HelloActivity@64e33b18 onResume
06-24 11:06:30.137 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.HelloActivity@64e33b18 onPause
06-24 11:06:30.287 665-685/? I/ActivityManager﹕ Displayed com.stackoverflow/.HelloActivity: +182ms
06-24 11:06:32.389 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.HelloActivity$1@64e356b0 finishes
06-24 11:06:32.389 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.HelloActivity@64e33b18 onDestroy
06-24 11:06:32.399 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.MainActivity@64e05830 onPause
06-24 11:06:32.399 27200-27200/com.stackoverflow E/ActivityThread﹕ Performing pause of activity that is not resumed: {com.stackoverflow/com.stackoverflow.MainActivity}
java.lang.RuntimeException: Performing pause of activity that is not resumed: {com.stackoverflow/com.stackoverflow.MainActivity}
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3015)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3003)
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2981)
at android.app.ActivityThread.access$1000(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1207)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
06-24 11:06:32.409 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.MainActivity@64e05830 onResume
06-24 11:06:32.769 27200-27200/com.stackoverflow I/System.out﹕ com.stackoverflow.AffinityTestActivity@64e22fc0 onDestroy
正如您所看到的,直到 HelloActivity 完成之后才调用 MainActivity 的 onPause 方法。这也是不对的。对我来说,这表明在任务被带到前台时在 onResume 中启动活动会导致生命周期中出现一些意外的冲突。
为了看看如果我给活动/任务一秒钟的时间来完成任何看不见的处理会发生什么,我使用了一个处理程序来调用 MainActivity 中的 HelloActivity 意图:
@Override
protected void onResume() {
System.out.println(this + " onResume");
super.onResume();
if (!skipHello) {
System.out.println(this+" starts "+HelloActivity.class.getSimpleName());
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(MainActivity.this, HelloActivity.class);
startActivity(intent);
}
}, 1000);
skipHello = true;
} else {
skipHello = false;
}
}
这导致了更好的行为。 HelloActivity 按其应有的方式运行,并且 onPause 没有被调用。显然,这对于工作代码来说并不理想,但它表明,只需将执行时间向前移动一秒就可以解决问题。任务内部调度冲突的更多证据。
接下来,我也尝试给 HelloActivity 赋予它自己的任务:
<activity
android:label="HELLO"
android:name="com.stackoverflow.HelloActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleTask"
android:taskAffinity=".DifferentTask">
</activity>
(郑重声明,此配置没有多大意义,但我认为它反映了实际项目中具有更合乎逻辑的目的的场景。)
在这种情况下,一切正常。 HelloActivity 的生命周期不会干扰 MainActivity 的生命周期。然而,它现在有自己的任务的开销以及运行活动的伴随问题singleTask
(点击“Home”按钮并重新打开应用程序将带您进入 MainActivity,使 HelloActivity 在其新任务中无法访问,即使它是关闭应用程序之前查看的最后一个活动)。
我最好的建议是找到一种方法来避免这种特殊情况。 :) 这似乎是 Android 更高版本中的一个错误,尽管是一个奇怪的边缘情况。如果这不是一个选择,您可以采用我用来绕过它的路线之一。我已经尝试了其他一些方法,但很难回避这样一个事实:调度是在我们掌握之外的操作系统级别进行控制的。
抱歉,我无法为您提供更深入的答案,但这就是我目前所能得到的全部!