2020-07-21 Activity中onNewIntent方
Activity 的 onNewIntent方法的调用可总结如下:
在该Activity的实例已经存在于Task和Back stack中(或者通俗的说可以通过按返回键返回到该Activity )时,当使用intent来再次启动该Activity的时候,如果此次启动不创建该Activity的新实例,则系统会调用原有实例的onNewIntent()方法来处理此intent.
且在下面情况下系统不会创建该Activity的新实例:
1,如果该Activity在Manifest中的android:launchMode定义为singleTask或者singleInstance.
2,如果该Activity在Manifest中的android:launchMode定义为singleTop且该实例位于Back stack的栈顶.
3,如果该Activity在Manifest中的android:launchMode定义为singleTop,且上述intent包含Intent.FLAG_ACTIVITY_CLEAR_TOP标志.
4,如果上述intent中包含 Intent.FLAG_ACTIVITY_CLEAR_TOP 标志和且包含 Intent.FLAG_ACTIVITY_SINGLE_TOP 标志.
5,如果上述intent中包含 Intent.FLAG_ACTIVITY_SINGLE_TOP 标志且该实例位于Back stack的栈顶.
上述情况满足其一,则系统将不会创建该Activity的新实例.
根据现有实例所处的状态不同onNewIntent()方法的调用时机也不同,总的说如果系统调用onNewIntent()方法则系统会在onResume()方法执行之前调用它.这也是官方API为什么只说"you can count on onResume() being called after this method",而不具体说明调用时机的原因.
三个测试Activity
分别为 ActivityA
、ActivityB
、ActivityC
默认启动模式为:
<activity android:name=".MainActivityA">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivityB" />
<activity android:name=".MainActivityC" />
默认点击事件
A → B、B → C、C → C
-
直接运行 生命周期变化打印日志
MainActivityA: onCreate: MainActivityA: onStart: MainActivityA: onResume: MainActivityA: onPause: MainActivityB: onCreate: MainActivityB: onStart: MainActivityB: onResume: MainActivityA: onStop: MainActivityB: onPause: MainActivityC: onCreate: MainActivityC: onStart: MainActivityC: onResume: MainActivityB: onStop: MainActivityC: onPause: MainActivityC: onCreate: MainActivityC: onStart: MainActivityC: onResume: MainActivityC: onStop:
-
修改
ActivityC
的launchMode
为singleTop
然后运行 生命周期变化打印日志:MainActivityA: onCreate: MainActivityA: onStart: MainActivityA: onResume: MainActivityA: onPause: MainActivityB: onCreate: MainActivityB: onStart: MainActivityB: onResume: MainActivityA: onStop: MainActivityB: onPause: MainActivityC: onCreate: MainActivityC: onStart: MainActivityC: onResume: MainActivityB: onStop: MainActivityC: onPause: MainActivityC: onNewIntent: MainActivityC: onResume: MainActivityC: onPause: MainActivityC: onNewIntent: MainActivityC: onResume:
-
在原配置上修改
ActivityB
的launchMode
为singleTop
,修改点击事件为A → B、B → C、C → B
然后运行 生命周期变化打印日志:MainActivityA: onCreate: MainActivityA: onStart: MainActivityA: onResume: MainActivityA: onPause: MainActivityB: onCreate: MainActivityB: onStart: MainActivityB: onResume: MainActivityA: onStop: MainActivityB: onPause: MainActivityC: onCreate: MainActivityC: onStart: MainActivityC: onResume: MainActivityB: onStop: MainActivityC: onPause: MainActivityB: onCreate: MainActivityB: onStart: MainActivityB: onResume: MainActivityC: onStop:
至此证明只有当singleTop修饰的Activity X在栈顶时,再次启动Activity X则会走onNewIntent
-
在上面那个示例中 将
ActivityB
的launchMode
从singleTop
修改为singleTask
, 然后运行 生命周期变化打印日志:MainActivityA: onCreate: MainActivityA: onStart: MainActivityA: onResume: MainActivityA: onPause: MainActivityB: onCreate: MainActivityB: onStart: MainActivityB: onResume: MainActivityA: onStop: MainActivityB: onPause: MainActivityC: onCreate: MainActivityC: onStart: MainActivityC: onResume: MainActivityB: onStop: MainActivityC: onPause: MainActivityB: onNewIntent: MainActivityB: onStart: MainActivityB: onResume: MainActivityC: onStop: MainActivityC: onDestroy:
我们可以看到被
singleTask
修饰的MainActivityB
,在C中启动时,先调用了onNewIntent
,然后继续走了onStart、onResume
-
将上述示例中的
singleTask
修改为singleInstance
,然后运行 生命周期变化打印日志:MainActivityA: onCreate: MainActivityA: onStart: MainActivityA: onResume: MainActivityA: onPause: MainActivityB: onCreate: MainActivityB: onStart: MainActivityB: onResume: MainActivityA: onStop: MainActivityB: onPause: MainActivityC: onCreate: MainActivityC: onStart: MainActivityC: onResume: MainActivityB: onStop: MainActivityC: onPause: MainActivityB: onNewIntent: MainActivityB: onStart: MainActivityB: onResume: MainActivityC: onStop:
结果同
singleTask
修饰的效果一样。 -
将上述示例中的
singleInstance
修改为singleTop
,并在C跳转B的Intent
上添加intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
然后运行 生命周期变化打印日志:MainActivityA: onCreate: MainActivityA: onStart: MainActivityA: onResume: MainActivityA: onPause: MainActivityB: onCreate: MainActivityB: onStart: MainActivityB: onResume: MainActivityA: onStop: MainActivityB: onPause: MainActivityC: onCreate: MainActivityC: onStart: MainActivityC: onResume: MainActivityB: onStop: MainActivityC: onPause: MainActivityB: onNewIntent: MainActivityB: onStart: MainActivityB: onResume: MainActivityC: onStop: MainActivityC: onDestroy:
再点击返回直到回退到桌面
MainActivityB: onPause: MainActivityA: onStart: MainActivityA: onResume: MainActivityB: onStop: MainActivityB: onDestroy: MainActivityA: onPause: MainActivityA: onStop: MainActivityA: onDestroy:
我们发现该实例的效果相当于启动
singleTask、singleInstance
的MainActivityB