Activity的生命周期和启动模式

1.典型情况下生命周期全面分析
这里写图片描述
上图是Activity的生命周期示意图:
onCreate和onDestory是配对的,分别标识Activiy的创建和销毁并且只可能调用一次。
onCreate表示Activity正在被创建这里可以做一些初始化工作,比如调用setContentView去加载布局资源.初始化Activity所需要的数据等;
onDesoty表示Activity被回收,在这里我们可以做一些回收工作和最终资源的释放;
onStart和onStop是配对的,从是否可见的角度来进行回调的,分别表示Activity是可见和不可见;
onStart表示Activity正在被启动,即将开始,这是Activity已经可见了,但是还没有出现在前台,无法和用户交互。这是可以理解为Activity已经显示出来了,但是用户还看不到。
onStop表示Activity即将停止。可以做一些轻量级的回收工作;
onResume和onPause是配对的,从是否位于前台的角度来回调的,分别表示Activity在前台和不再前台;
onRsume表示Activity已经可见了,并且出现在前台并开始活动了。
onPause表示Activity正在停止,正常情况下,紧接着onStop就会被调用,在极端情况下,如果这个时候,在快速返回当前Activity,那么onResume会被调用。这里可以做停止动画等工作,但是不能太耗时。
onRestart表示Activity正在重新启动,表示Activity从onStop(不可见)到onStart(可见)状态。

对于一个Activity A来说:
1.第一次启动 回调 onCreate——>onStart——>onResume.
2.当用户打开新的Activity B或者切换到桌面的时候,回调 onPause——>onStop
如果新打开Activity B 采用了透明主题或者Diaolg样式,回调 onPause,这时并不会执行onStop
3.当用户再次回到Acitivity时候,回调 onRestart——>onStart——>onResume;
4.当用户调用了Activity的finish或者按back键回退时,回调 onPause——>onStop——>onDestory
5.当Activity被系统回收再次打开,生命周期方法回调过程按上图来执行,只是生命周期方法一样,不代表多有过程都一样,比如异常情形下的onRestoreInstanceState和onSaveInstanceState会执行;
由Activity A启动 Activity B 过程 onPause(A)——>onCreate(B)——>onStart(B)——>onResume(B)——onStop(A);
在onPause和onStop中都不能做耗时的操作,尤其是onPause,我们应当尽量在onStop中操作,从而使得新的Activity尽快显示出来并切换到前台。

2.异常情况下的生命周期分析
所谓异常情况:比如资源相关的系统配置发生改变或者系统内存不足时等等,这时候Activity可能会被杀死;
这里写图片描述
上面是异常情况下Activity的重建过程;
当Activity被异常销毁的时候,其onPause,onStop,onDestoty均会被调用,同时由于Activity是在异常状况下销毁的,系统会调用onSaveInstaceState来保存当前Activity的状态。这个方法调用时机在onStop之前,它和onPause没有既定的时序关系,可在它前面调用,也可在它后面调用,
onSaveInstance方法只出现在异常情况下,正常情况下系统不会回调这个方法。
当Activity异常情况被重新创建后,系统会调用onRestoreInstaceState,并且把Activity销毁时onSaveInstace方法所保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法,这两个方法都可以从Bundle中取值;
onRestoreInstaceState的调用时机在onStart之后
当Activity被异常销毁的时候,系统默认会为我们保存当前Activity的视图结构,并且Activity重启后为我们保存这些数据。比如Edittext的输入文字,ListView滚动的位置等;这里面用到的是一种委托的思想,当Activity被销毁的时候,Activity会调用onSaveInstanceState保存数据,同时委托Window去保存数据,接着Window再委托顶级容器去保存数据,顶层容器在一一通知它的子元素来保存数据。
在介绍一下Actiivity优先级情况:
1.前台Activity——正在和用户交互的Activity,优先级最高
2,Activity被看见但不是在前台——比如Activity中弹出了一个对话框,导致Activity可见但位于后台无法和用户直接交互。
3.后台Activity——比如执行了onStop,优先级最低
当内存不足时,系统会按照上面优先级去杀死目标Activity所在的进程,并后续通过onSaveInstanceState和onRestoreInstanceState来存储和恢复数据。
另外一个进程中如果没有四大组件,那么这个进程很容易就被系统回收,一些后台工作不适合脱离四大组件而独自运行在后台中,这样很容易被回收,比较好的办法是放在service中。

从上面可以知道系统配置发生改变后,Activity会被重建。其实也有办法不重建Activity。
系统配置中有很多内容,如果当某项内容发生改变后,我们不想创建Activity,可以给Activity指定configChanges属性。比如android:configChanges=”orientation”可以让屏幕旋转的时候不会重新创建。当然希望指定多个值可以使用 “|”;
一些常用的configChanges的项目和含义

项目含义
locale设备的本地位置发生了改变,一般指切换系统语言
keyboardHidden键盘的可访问性发生了改变,比如用户调出了键盘
orientation屏幕方向发生了改变,比如旋转了手机屏幕
screenSize当屏幕的尺寸信息发生了改变,当旋转屏幕时候,屏幕的尺寸会发生改变,这个选项比较特殊,他和编译选项有关,当编译选项中的minSdkVersion和targetSdkVersion均低于13时,此选项不会导致Activity重启,否则会导致屏幕重启
smallestScreenSize设备的物理屏幕尺寸发生改变,这个项目和屏幕的方向没关系,仅仅表示在实际物理屏幕尺寸发生改变的时候,比如用户切换到了外部的显示设备,这个选项和screenSize一样,当编译选项中的minSdkVersion和targetSdkVersion均低于13时,此选项不会导致Activity重启,否则会导致屏幕重启

从上表可知,如果我们没有在Activity的configChanges属性中指定该选项的话,当配置发生改变后,就会导致Activity重新创建。
当我们设置了configChanges之后,系统不会调用onSaveInstance和onRestoreInstanceState,取而代之会调用Activity的onConfigurationChanged方法:比如
AndroidMenifest.xml中设置 android:configChanges=”orientation|screenSize”

        <!--minSdkVersion和targetSdkVersion有一个大于13所以,android:configChanges="orientation|screenSize"-->
         <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />
        <activity
            android:name="com.app.mode.MainActivity"
            android:configChanges="orientation|screenSize" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

当旋转屏幕的时候,Activity里面会调下面这个方法:

@Override
    public void onConfigurationChanged(Configuration newConfig) {

        super.onConfigurationChanged(newConfig);
    }

Activity(活动)的启动模式详解
Activity的标志位(Flags)
FLAG_ACTIVITY_NEW_TASK 与Activity中指定singleTask效果一样
FLAG_ACTIVITY_SINGLE_TOP:与Activity中指定singleTop效果一样
Activity隐式启动时候IntentFilter的匹配规则
使用隐式启动Activity的时候,当程序不匹配Intent的时候,有可能会报错
这时候使用一下两种方法可以避免:

    //i是你要启动的Intent         
    //1.resolveActivity 如果返回结果为null就是不匹配,它返回的是最佳的Activity
    //通过返回值就可规避上述风险,MATCH_DEFAULT_ONLY仅仅匹配哪些在Activity中声明了
    //<category android:name="android.intent.category.DEFAULT" />的category
    ResolveInfo mInfo = getPackageManager().resolveActivity(i,
                        PackageManager.MATCH_DEFAULT_ONLY);
    ComponentName mName = i.resolveActivity(getPackageManager());

    //2.queryIntentActivities返回的是所有成功匹配的Activity信息
    List<ResolveInfo> mResolveInfos = getPackageManager()
                        .queryIntentActivities(i,PackageManager.MATCH_DEFAULT_ONLY);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值