Skip to content

2019-09-02:Activity中onNewIntent方法的调用时机和使用场景? #138

Open

Description

@Moosphan
No description provided.

Activity

  1. DogLaShi commented on Sep 2, 2019

    @DogLaShi

    当目标activity启动模式为singleTop的时候,并且目标activity之前已经存在了,这时启动目标activity就会走onnewintent方法

  2. 103style commented on Sep 2, 2019

    @103style

    @DogLaShi 你的回答 还得加上 当 singleTop的activity在栈顶时的条件。

  3. zhaoerlei1989 commented on Sep 2, 2019

    @zhaoerlei1989

    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",而不具体说明调用时机的原因.

  4. 103style commented on Sep 2, 2019

    @103style

    三个测试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

    Intent Flags 的官方介绍

  5. gabyallen commented on Sep 2, 2019

    @gabyallen

    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=“singleInstance”,或者intent.setFlags(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",而不具体说明调用时机的原因.

  6. bukeCN commented on Sep 2, 2019

    @bukeCN

    调用时机是为 Activity 设置了特殊的启动模式(主要是两种 single 模式)或者添加了可复用的 FLAG 时会调用,通俗讲就是当需要复用 activity 时会调用此方法。

  7. yangfanggang commented on Sep 2, 2019

    @yangfanggang

    各位大佬说的很好 我是小黑

  8. IT666 commented on Sep 27, 2019

    @IT666

    onNewIntent的调用时机:只要该Activity实例在栈中存在,每次复用Activity的时候,都会调用onNewIntent,而不会重新创建Activity实例。
    singleTop、singleTask、singleInstance模式下都会调用onNewIntent()。
    调用onNewIntent()生命周期如下:onNewIntent()->onRestart()->onStart()->onResume()。
    注意:在onNewIntent()中一定要设置setIntent(intent),否则getIntent()时获取到的是旧的intent,而不是新的intent。

  9. mlinqirong commented on Dec 14, 2021

    @mlinqirong

    onNewIntent的调用时机:只要该Activity实例在栈中存在,每次复用Activity的时候,都会调用onNewIntent,而不会重新创建Activity实例。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions