关于android:Bug:onNewIntent没有使用Intent.FLAG_ACTIVITY_NEW_TASK调用singleTop活动

Bug: onNewIntent not called for singleTop activity with Intent.FLAG_ACTIVITY_NEW_TASK

startActivity中似乎有一个错误。

通过在androidmanifest.xml中将活动设置为具有不同taskAffinitysingleTop并使用Intent.FLAG_ACTIVITY_NEW_TASK调用startActivity时,可以在两个任务中创建两个活动(每个任务一个活动)。

再次调用startActivity将返回第一个活动/任务,调用onNewIntent。但是,第四次调用startActivity将返回到第二个活动/任务,但不调用onNewIntent

这两个任务之间唯一的区别是它们的taskAffinity。不知何故,观察到不对称行为。

但是,如果还使用了Intent.FLAG_ACTIVITY_SINGLE_TOP,则按预期调用onNewIntent

似乎androidmanifest.xml中的singleTopIntent中的Intent.FLAG_ACTIVITY_SINGLE_TOP不同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class ActivityA extends Activity implements OnClickListener {
    private String tag;

    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        tag = getClass().getName();
        Log.v(tag,"onCreate()");

        setContentView(R.layout.main);
        Button button = (Button)findViewById(R.id.button);
        button.setText(tag.endsWith("ActivityA") ?"Activity B"
                :"Activity A");
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Intent intent;
        int flags = Intent.FLAG_ACTIVITY_NEW_TASK
        // | Intent.FLAG_ACTIVITY_SINGLE_TOP
        ;

        Log.v(tag,"onClick()");

        intent = new Intent(this,
                tag.endsWith("ActivityA") ? ActivityB.class
                        : ActivityA.class);
        intent.setFlags(flags);
        startActivity(intent);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        Log.v(tag,"onNewIntent()");
    }
}
1
2
3
public class ActivityB extends ActivityA {

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test"
    android:versionCode="1"
    android:versionName="1.0">
    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name">

        <activity
            android:name=".ActivityA"
            android:launchMode="singleTop"
            android:label="Activity A">
            <intent-filter>
                <action
                    android:name="android.intent.action.MAIN" />
                <category
                    android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".ActivityB"
            android:launchMode="singleTop"
            android:label="Activity B"
            android:taskAffinity="activity.B">
        </activity>

    </application>
</manifest>

这有点晚了,但自从我刚遇到这个-正如马特提到的,在清单和意图中的标记活动单顶部是不一样的(至少在以前的Android版本上)。

startActivityUncheckedLocked法中:

关于姜饼-https://github.com/android/platform_frameworks_base/blob/gingerbread/services/java/com/android/server/am/activitystack.java

看2204号线--

1
2
 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
                                && taskTop.realActivity.equals(r.realActivity)) {

所以它只是检查目的上的启动标志,而不是检查清单。将其与Jellybean MR1释放进行比较:

https://github.com/android/platforms_frameworks_base/blob/jb-mr1-release/services/java/com/android/server/am/activitystack.java

看2835行--

1
2
3
                if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
                        || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
                        && taskTop.realActivity.equals(r.realActivity)) {

因此,在MR1中,他们似乎在检查r.launchmode(可能是AndroidManifest.xml值)以及launchFlags(可能是意图本身),而在旧版本中,他们只检查意图标志。

它实际上是在2012年2月16日确定的,在此承诺中:https://github.com/android/platforms_frameworks_base/commit/f363dfd26c304bca33f12065a9ed3de29191193962

短版本是-在意图和清单中设置单个顶部标志。

(感谢对Android Bug跟踪器中相关Bug的评论,我指向了要查找的源文件-http://code.google.com/p/android/issues/detail?ID=4155×C9)。