Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Moosphan opened this issue Sep 2, 2019 · 9 comments

Comments

@Moosphan
Copy link
Owner

Moosphan commented Sep 2, 2019

No description provided.

@DogLaShi
Copy link

DogLaShi commented Sep 2, 2019

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

@103style
Copy link

103style commented Sep 2, 2019

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

@zhaoerlei1989
Copy link

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

@103style
Copy link

103style commented Sep 2, 2019

三个测试Activity分别为 ActivityAActivityBActivityC

默认启动模式为:

 <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: 
    
  • 修改 ActivityClaunchModesingleTop 然后运行 生命周期变化打印日志:

    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: 
    
  • 在原配置上修改 ActivityBlaunchModesingleTop,修改点击事件为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

  • 在上面那个示例中 将ActivityBlaunchModesingleTop 修改为 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、singleInstanceMainActivityB

Intent Flags 的官方介绍

@gabyallen
Copy link

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

@bukeCN
Copy link

bukeCN commented Sep 2, 2019

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

@yangfanggang
Copy link

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

@IT666
Copy link

IT666 commented Sep 27, 2019

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

@mlinqirong
Copy link

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

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

No branches or pull requests

9 participants