Activity生命周期 和 启动模式

本文主要是分析Activity各生命周期的变化,以及在不同启动模式下对生命周期的影响;

  • Activity lifecycle
  • Launch Mode 
  • Intent flags

  • Handling affinities

  分别有MainActivity、Main1Activity、Main2Activity三个activity(以下用0、1、2代替,默认启动模式)来进行测试;

  adb shell dumpsys activity 查看当前activity堆栈信息

  •  Activity lifecycle       

首先看android官方Activity-lifecycle concepts

1.1:正常启动一个activity按back键返回

可以看到新建了一个activity实例,先走了 onCreate -- onStart -- onResume启动0;

然后走onPause -- onStop -- onDestroy销毁0;

1.2:启动activity后按Home键

 没有销毁Activity,然后重新开启

走了restart流程 onRestart -- onStart -- onResume

1.3:两个activity之间进行切换

新启动了1实例;0先走OnPuase,然后1走启动流程;

1走了onResume之后,0才走onStop,但还是没有销毁;

如果此时按Back键返回

 0因为没有销毁所以走restart流程,当0可用之后(onResume),1走销毁流程; 


    总结:

     activity的创建和销毁:OnCreat、OnDestory

     activity可见和不可见:OnStart、OnStop

     activity可用和不可用:OnResume,OnPause

     activity不可见时开启:OnRestart

     activity之间相互切换:0先走不可用(OnPause),1可用(OnResume)之后,0走不可见(OnStop)

     back键会走销毁流程(OnDestory),Home键会走不可见流程(OnStop)

  • Launch Mode 

2.1 standard(默认模式)

默认值。系统在启动该 Activity 的task(任务)中创建 Activity 的新实例,并将 intent 传送给该实例。Activity 可以多次实例化,每个实例可以属于不同的task,一个task可以拥有多个实例。

  2.1.1 依次开启activty 0-1-2-2

 

可以看到2创建了两次 不一样的实例,Task#218中也存在四个activity实例;

2.2 singleTop

如果当前任务的顶部已存在 Activity 的实例,则系统会通过调用其 onNewIntent() 方法来将 intent 转送给该实例,而不是创建 Activity 的新实例。Activity 可以多次实例化,每个实例可以属于不同的任务,一个任务可以拥有多个实例(但前提是返回堆栈顶部的 Activity 不是该 Activity 的现有实例)。

  2.2.1 2的启动模式改为singleTop,依次开启activty 0-1-2-2

 2只创建了一次,第二次启动先走了OnPause,然后才走OnNewIntent;Task#220存在三个activity,由于没有重新走创建activity,   所以该启动模式为栈顶复用,但是要先走OnPause;

  2.2.2 0的启动模式设置为singleTop,依次开启activty 0-1-2-0

 如果不在task顶部,就会走标准模式;

2.3 singleTask

系统会创建新任务,并实例化新任务的根 Activity。但是,如果另外的任务中已存在该 Activity 的实例,则系统会通过调用其 onNewIntent() 方法将 intent 转送到该现有实例,而不是创建新实例。Activity 一次只能有一个实例存在。

 2.3.1  0的启动模式设置为singeTask  依次开启activty 0-1-2-0

 0只创建了一次,第二次启动先走了OnNewIntent,然后进入reStart流程;

 1和2都被销毁了,Task#224中只存在0这一个activity,所以该模式为栈内复用;

2.3.2  1的启动模式设置为singeTask  依次开启activty 0-1-2-1

   这次在Task#230中存在0、1两个activity,说明singleTask模式在复用activity的时候销毁了在它之上的activity;

2.3.3  2的启动模式设置为singeTask  依次开启activty 0-1-2-2

2.4 singleInstance

与 "singleTask" 相似,唯一不同的是系统不会将任何其他 Activity 启动到包含该实例的任务中。该 Activity 始终是其任务唯一的成员;由该 Activity 启动的任何 Activity 都会在其他的任务中打开。

     2.4.1  2的启动模式设置为singeInstance  依次开启activty 0-1-2-2

 2只创建了一次,第二次启动先走了OnPause,然后才进入OnNewIntent;

但0、1位于Task#236,2位于Task#237;

     2.4.2  0的启动模式设置为singeInstance  依次开启activty 0-1-2-0

  0只创建了一次,第二次启动先走了OnNewIntent,然后进入reStart流程;

 所以该模式为单例模式,它独享一个Task;


总结:

standard:每次启动activity都重新创建实例,加入到当前Task中;

singleTop:栈顶复用,复用activity时走OnPause-OnNewIntent-OnResume;

singleTask:栈内复用,一个Task中只能存在一个该activity实例;复用activity时走OnNewIntent-OnRestart-OnStart-OnResume

singleInstance:全局复用,单例模式,系统中只存在一个该Activity实例;

复用流程:三种非标准模式当activity位于Task顶部时,重新启动自己都会先走OnPause,然后走OnNewIntent-OnResume;

               如果activity不在Task顶部,另外两种启动模式在重新启动自己时;都会先走OnNewIntent,然后进入reStart流程;

  • 3.Intent flags

启动activity时,可以通过在传递给startActivity()的意图中包含标志来修改activity与其Task的默认关联。

Intent intent = new Intent(MainActivity.this, Main1Activity.class); mContext.startActivity(intent.addFlags(Intent.XXX));

FLAG:FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_SINGLE_TOP、 FLAG_ACTIVITY_CLEAR_TOP

3.1 FLAG_ACTIVITY_NEW_TASK

3.1.1: 0通过startActivity启动1时添加该FLAG

 1走创建流程,Task#245中存在0、1两个activity;

 3.1.2 0先启动1,然后1启动0时添加FLAG

 0走了两次创建流程,Task#246中也存在两个0的实例;

 所以单独设置该FLAG没有任何作用;

3.2 FLAG_ACTIVITY_SINGLE_TOP

    3.2.1: 0先启动1,1再通过startActivity启动自己并添加该FLAG

从日志就可以看出该flag等同于singleTop; 

3.3 FLAG_ACTIVITY_CLEAR_TOP

      3.3.1: 0先启动1,1通过该FLAG启动自己;

 1启动了两次,但在第二个activity可用之后第一个走了销毁流程;

      3.3.2:0先启动1,然后1通过该FLAG启动0;

Task#252中只有一个activity0,所以当Task中已经存在该activity,该FLAG的作用为清空在其之上的所有activity;

如果该activity为标准模式,会重新创建该实例后加入当前Task,其他模式则走复用流程;

  • 4.Handling affinities

 taskAffinity指示activity属于哪个Task。 默认情况下,同一应用程序中的所有activity都具有相互关联性。 因此,默认情况下,同一应用程序中的所有activity都希望属于同一Task。 但是,可以修改activity的默认affinity。 在不同应用程序中定义的activity可以共享affinity,或者可以在同一应用程序中定义的activity分配不同的Task affinity。

affinity在两种情况下起作用:1.startActivity时包含FLAG_ACTIVITY_NEW_TASK,2. activity的属性allowTaskReparenting为true;

 4.1  taskAffinity+FLAG_ACTIVITY_NEW_TASK

1的taskAffinity为"com.task.one",0和2均为默认包名;

先从0启动1,然后依次执行1-->2-->1--->2--->1,其中2开启1的时候会添加FLAG_ACTIVITY_NEW_TASK

 1开启了三次,第三次开启时没有反应,Task#277中有0、1、2,Task#278中有1、2

 2在第一次开启1的时候配置了android:taskAffinity = "com.task.one"和FLAG_ACTIVITY_NEW_TASK;

 第二次开启1系统会在配置了以上属性的Task中寻找对应的activity,找到了想复用,但没有对2做任何操作,所以无法成功复用;

4.2   taskAffinity+FLAG_ACTIVITY_NEW_TASK+FLAG_ACTIVITY_CLEAR_TOP

还是上面的流程,2开启1的时候会同时添加FLAG_ACTIVITY_NEW_TASK、FLAG_ACTIVITY_CLEAR_TOP

 


 这一次可以看出1开启成功,Task中其他Activity跟单独使用FLAG_ACTIVITY_CLEAR_TOP一样

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值