Ошибка: onNewIntent не вызывается для singleTop-активности с Intent.FLAG_ACTIVITY_NEW_TASK
В startActivity
появляется ошибка.
Установив действия singleTop
с различными taskAffinity
в AndroidManifest.xml и используя Intent.FLAG_ACTIVITY_NEW_TASK
при вызове startActivity
, два действия могут быть созданы в двух задачах (по одному действию на задачу).
Вызов startActivity
снова вернется к первому действию/задаче и вызывается onNewIntent
. Однако при вызове startActivity
четвертое время вернется ко второму действию/задаче, но onNewIntent
не вызывается.
Единственное различие между двумя задачами - их taskAffinity
. Так или иначе, наблюдается асимметричное поведение.
Однако, если используется Intent.FLAG_ACTIVITY_SINGLE_TOP
, тогда onNewIntent
вызывается как ожидалось.
Похоже, что singleTop
в AndroidManifest.xml не совпадает с Intent.FLAG_ACTIVITY_SINGLE_TOP
в Intent
.
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()");
}
}
public class ActivityB extends ActivityA {
}
<?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>
Ответы
Ответ 1
это немного поздно, но так как я только что наткнулся на это -
как отмечает Мэтт, активность одного флага в манифесте и в намерении не совпадают (по крайней мере, в предыдущих версиях андроида).
в startActivityUncheckedLocked
:
на пряниках -
https://github.com/android/platform_frameworks_base/blob/gingerbread/services/java/com/android/server/am/ActivityStack.java
Посмотрите на строку 2204 -
if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
&& taskTop.realActivity.equals(r.realActivity)) {
поэтому он просто проверяет флаги запуска на намерение и не проверяет манифест. сравните это с выпуском jellybean mr1:
https://github.com/android/platform_frameworks_base/blob/jb-mr1-release/services/java/com/android/server/am/ActivityStack.java
посмотрите строку 2835 -
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
(предположительно самого намерения), тогда как в более старых версиях они проверяли только флаги намерения.
это было фактически зафиксировано 16 февраля 2012 года в этой фиксации:
https://github.com/android/platform_frameworks_base/commit/f363dfd26c304bca33f12065a9ed3de291193962
короткая версия - установить единственный верхний флаг как в намерении, так и в манифесте.
(благодаря этому комментарию связанная ошибка в трекере ошибок Android, указав мне, в какой исходный файл посмотреть - http://code.google.com/p/android/issues/detail?id=4155#c9).