Activity的生命周期和启动模式

activity的生命周期

正常情况下activity的生命周期

如下图所示:

整个生命周期,onCreate 和onDestroy,onStart和onStop,onResume和onPause都是一一配对的。

问题

当前Activity为A,用户打开新的ActivityB,B的onResume和A的onPause方法那个先执行?

当启动一个新的activity是,旧的activity的onPause会先执行,然后启动新的activity。具体执行流程:A.onPause——B.oncCreate——B.onStart——B.onResume——A.onStop。

异常情况下activity生命周期

activity除了随着用户操作调用生命周期的方法外,还会有异常情况。比如系统配置发生变化和系统内存不足时的异常情况。

1.系统配置发生变化导致activity被杀死和创建

当系统配置发生变化后,activity可能会被销毁,系统会调用onSaveInstanceState保存当前activity的状态,onSaveInstanceState一定发生在onStop方法之前,和onPause方法没有关系,可能在前可能在后发生。当activity重新创建的时候,系统会调用onRestoreInstanceStateonCreate方法获取保存的数据然后可以恢复。当然onRestoreInstanceState的调用时机也一定在onStart之后。activity委托window自动已经帮我们做了一些恢复工作,可以查看每个view的onSaveInstanceState和onRestoreInstanceState方法的具体实现。onSaveInstanceState只会在activity即将被销毁并且有机会重新显示的情况才会调用。比如屏幕旋转的异常销毁,会创建新的activity显示。普通的正常销毁并不会调用onSaveInstanceState方法。

  @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

onRestoreInstanceStateonCreate的区别

onRestoreInstanceState一旦被调用,参数Bundle savedInstanceState肯定是有值的,不用额外判空。而onCreate正常启动时,参数Bundle savedInstanceState肯定是null,必须做额外的判断才能恢复数据。所以说用onRestoreInstanceState简单一些。

系统配置发生变化时,让activity不重新创建

给activity设置configChanges属性,比如设置屏幕旋转时,不重新创建activity就设置

 android:configChanges="orientation"

想设置多个值用“|”隔开。常用的有locale、orientation、keyboardHidden等其他自行查看。

这种情况下不会重启activity,也不会调用onSaveInstanceState和onRestoreInstanceState方法存储恢复数据,取而代之的调用了onConfigurationChanged方法

  @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }

2.内存不足导致activity被杀死

系统会根据activity优先级杀死目标activity来腾出内存空间,和上面情况1一样的数据存储和恢复。

activity的启动模式

activity的四种launchmode

1.standard:标准模式

系统默认模式,只要启动一个activity就会创建一个activity实例,不管这个实例存不存在,这种模式下,谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈中。这个Activity它的onCreate(),onStart(),onResume()方法都会被调用。

2.singleTop:栈顶复用模式

如果新的activity已经位于栈顶,那么这个Activity不会被重写创建,同时它的onNewIntent()方法会被调用,通过此方法的参数我们可以去除当前请求的信息。如果栈顶不存在该Activity的实例,则情况与standard模式相同。需要注意的是这个Activity它的onCreate(),onStart()方法不会被调用,因为它并没有发生改变。

3.singleTask:栈内复用模式

这个模式比较复杂,当一个具有singleTask模式的Activity A请求启动后,系统会寻找A想要的任务栈,这个任务栈就是通过taskAffinity属性指定,后面会做介绍。如果不存在,需要创建一个A想要的任务栈,然后在创建A的实例后把A放到栈中;如果已经存在A想要的任务栈,这时需要判断A是否在栈中有实例存在,如果存在,那么系统会把A掉到栈顶并调用onNewIntent方法,与此同时singleTask默认有clearTop效果,这样A上面的Activity会全部出栈;如果不存在A的实例,则创建A的实例并把A放入栈中。

4.singleInstance:单实例模式

该模式具备singleTask模式的所有特性外,与它的区别就是,这种模式下的Activity会单独占用一个Task栈,具有全局唯一性,即整个系统中就这么一个实例,由于栈内复用的特性,后续的请求均不会创建新的Activity实例,除非这个特殊的任务栈被销毁了。以singleInstance模式启动的Activity在整个系统中是单例的,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。

TaskAffinity

顾名思义,任务相关性。这个参数设置了Activity所需要的任务栈的名字,默认情况下,所有Activity所需要的任务栈的名字都为应用的包名,可以通过taskAffinity为Activity设定任务栈的名字(除包名以为,不然相当于没有设定)。

<activity
           android:name=".view.ThirdActivity"
           android:taskAffinity=".ThirdActivity"
           android:launchMode="singleTask">
</activity>

注意点:

  1. taskAffinity属性主要和singleTask启动模式或者allowTaskReparenting属性配对使用,其他情况下没有意义。

  2. taskAffinity属性值为字符串,而且中间必须要有包名分隔符“.”这个符号,否则无法安装,会报错

    Installation failed with message INSTALL_FAILED_USER_RESTRICTED: Invalid apk.

allowTaskReparenting用来标记Activity能否从启动的Task移动到taskAffinity指定的Task,默认是继承至application中的allowTaskReparenting=false,如果为true,则表示可以更换;false表示不可以。

allowTaskReparenting = "true"

例如:

在一个E-Mail邮件内容中,包含一个web页的链接,点击它就会启动一个Activity来显示这个页面。但是这个Activity是由浏览器应用程序定义的,那么现在它作为e-mail Task(任务)的一部分。如果它重新宿主到Browser Task里,当Browser下一次进入到前台时,它就能被看见(上一次从邮件中打开的地址),并且,当e-mail Task再次进入前台时,就看不到它了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值