Activity的生命周期

2019-08-05  本文已影响0人  取了个很好听的名字

前言

本文主要说明了Activity的声明周期的相关内容

1正常生命周期流程

首先看一下正常的打开activity然后关闭activity所走的生命周期流程如下所示

08-05 11:37:36.955 24898-24898/com.zhqy.activitylifecycledemo E/MainActivity: onCreate: 
08-05 11:37:36.957 24898-24898/com.zhqy.activitylifecycledemo E/MainActivity: onStart: 
08-05 11:37:36.957 24898-24898/com.zhqy.activitylifecycledemo E/MainActivity: onResume: 
08-05 11:37:50.190 24898-24898/com.zhqy.activitylifecycledemo E/MainActivity: onPause: 
08-05 11:37:50.874 24898-24898/com.zhqy.activitylifecycledemo E/MainActivity: onStop: 
08-05 11:37:50.875 24898-24898/com.zhqy.activitylifecycledemo E/MainActivity: onDestroy: 

这就是一个activity正常的打开关闭生命周期所调用的方法,下面对这些方法进行方法说明。

onCreate:当前Activity正在创建,通过 setContentView(R.layout.activity_main);
方法可以将xml生成一个View加载到该界面上,这也是activity声明周期所调用的第一个方法。处于该方法时可以调用activity创建相关的方法。

onStart:当前的Activity正在启动,但界面还没有出现在前台(该activity在后台),还无法与用户进行交互(还没有获得焦点)。处于该方法时可以调用activity创建相关的方法。

onResume:当前Activity处于前台且已经可以与用户进行交互(获得焦点),当调用该方法时可能会有几种可能性,(1)activity第一次运行执行到了该方法(2)用户从另一个Activity回到该Activity时会执行该方法(例如切换activity,dilog消失)(3)用户从另一个Activity回到该Activity时,由于系统内存紧张将该activity进行了回收,当再次返回该activity时会重新走Activity创建的方法,也会走到该方法。在该方法中可以进行数据和恢复和展示。不要做耗时操作。

onPause:当Activity还可见(或部分可见)时调用该方法,此时Activity失去了与用户进行交互的能力,但仍处于前台。在该方法中可以进行数据的保存以及动画的移除等操作。不要做耗时操作,这样会影响下一个Activity的打开速度。

onStop:该Activity已经完全不可见并处于后台是调用该方法。在该方法中可以做一些耗时操作和资源的回收和销毁。

onDestory:该Activity即将销毁时会调用该方法。可以做一些资源回收工作。

1.1常见场景的生命周期调用

(1)第一次运行Activity:onCreate->onStart->onResumse->运行状态
(2)关闭Activity:运行状态->onPause->onStop->onDestory->结束Activity
(3)页面被部分遮盖(弹出dialog):onResumse->onPause
(4)页面部分遮盖->完全显示:onPause->onResume->运行状态
(5)页面处于后台->处于运行状态:onStop->onRestart->onStart->onResume->运行状态

2非正常的生命周期

由于横竖屏切换,软键盘弹出等或者由于系统内存紧张杀死当前Activity等事件引起的Activity的销毁与重建。

2.1由于资源配置引起的系统相关配置发生改变引起activity的销毁与重新创建

由于横竖屏切换,键盘可见性的变化引起的系统配置发生改变,如果没有进行设置的话,默认会引起Activity的销毁与重新创建,当然我们也可以阻止这种Activity的销毁与重新创建。下面以横竖屏切换为例说明。

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        >
        <activity android:name=".MainActivity"
            android:screenOrientation="sensor"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

这里我指定了 android:screenOrientation="sensor",使得当用户用户旋转设备时,页面也跟着发生横竖屏的切换。当页面处于运行状态下发生横竖屏切会发生什么看看会发生什么。当处于竖屏状态下调用的生命周期:

08-05 14:16:15.873 30006-30006/? E/MainActivity: onCreate: 
08-05 14:16:15.874 30006-30006/? E/MainActivity: onStart: 
08-05 14:16:15.875 30006-30006/? E/MainActivity: onResume: 

当发生横竖屏切换时调用的生命周期方法:

08-05 14:17:00.966 30006-30006/com.zhqy.activitylifecycledemo E/MainActivity: onPause: 
08-05 14:17:00.971 30006-30006/com.zhqy.activitylifecycledemo E/MainActivity: onStop: 
08-05 14:17:00.972 30006-30006/com.zhqy.activitylifecycledemo E/MainActivity: onDestroy: 
08-05 14:17:01.032 30006-30006/com.zhqy.activitylifecycledemo E/MainActivity: onCreate: 
08-05 14:17:01.033 30006-30006/com.zhqy.activitylifecycledemo E/MainActivity: onStart: 
08-05 14:17:01.034 30006-30006/com.zhqy.activitylifecycledemo E/MainActivity: onResume: 

从打印的日志来看当发生横竖屏切换时,默认情况下会将当前的Activity销毁并创建一个新的Activity。但是既然是发生了非正常的生命周期方法的调用,肯定与正常的生命周期方法调用不同,不同之处在于数据的保存。在非正常的生命周期下,Activity会调用onSaveInstanceState方法来保存相关控件的数据,需要保存的数据也可以通过该方法进行保存。当重新创建Activity时会通过onRestoreInstanceState方法恢复在onSaveInstanceState方法中保存的数据。系统默认通过Bundle进行数据的保存。

08-05 14:29:31.356 5605-5605/com.zhqy.activitylifecycledemo E/MainActivity: onPause: 
08-05 14:29:31.368 5605-5605/com.zhqy.activitylifecycledemo E/MainActivity: onSaveInstanceState: 
08-05 14:29:31.368 5605-5605/com.zhqy.activitylifecycledemo E/MainActivity: onStop: 
08-05 14:29:31.369 5605-5605/com.zhqy.activitylifecycledemo E/MainActivity: onDestroy: 
08-05 14:29:31.408 5605-5605/com.zhqy.activitylifecycledemo E/MainActivity: onCreate: 
08-05 14:29:31.409 5605-5605/com.zhqy.activitylifecycledemo E/MainActivity: onStart: 
08-05 14:29:31.409 5605-5605/com.zhqy.activitylifecycledemo E/MainActivity: onRestoreInstanceState: 
08-05 14:29:31.409 5605-5605/com.zhqy.activitylifecycledemo E/MainActivity: 恢复出来的数据123
08-05 14:29:31.410 5605-5605/com.zhqy.activitylifecycledemo E/MainActivity: onResume: 

这里需要注意的是:onSaveInstanceState会在onStop之前调用,该方法的调用顺序与onPause无关,onRestoreInstanceState会在onStart之后调用,该方法的调用顺序与onResume无关(无关的意思是可能在之前调用,也可能在之后调用)。

Activity销毁与创建.png

2.2由于内存资源不足导致的Activity的销毁与重新创建

这种情况下与情况2.1的所走的生命周期一致,不在重述。这里说明一下Activity的优先级(优先级从高高低):
(1)前台Activity:用户正在访问的页面
(2) 可见但不可互动的Activity:当前页面可见但是无法与用户进行交互(弹出dialog对话框或者当前页面被部分遮盖)
(3) 后台Activity:已经暂停的Activity(执行了onStop方法)

当系统内存不足时会按照上述的优先级杀死Activity,其数据可以通过onSaveInstanceState进行存储在onRestoreInstanceState进行回复。需要注意的是:当进程中没有四大组件运行时,该进程会很快被杀死,所以后台工作一定要放在四大组件中运行,保证进程有一定的优先级。这里附一张Activity的生命周期图。

activity声明周期.png
刚才说到默认情况下非正常的生命周期会发生Activity的销毁与重新创建,那么如何阻止Activity的销毁呢?答案是给Activity设置configChanges,比如说如果我们不想再屏幕旋转时重新创建Activity可以设置 android:configChanges="orientation|screenSize",这样在发生横竖屏切换时Activity将不会销毁。这样的系统设置很多,现在捡主要的进行说明:
变量名 含义
local 设备的本地地址发生改变,一般指切换了系统语言
keyboard 键盘类型发生了改变,比如外接了键盘
keyboardHidden 键盘的访问性发生了改变,比如用户调出了键盘
screenLayout 屏幕布局发生了改变,比如用户激活了另一个显示设备
orientation 屏幕方向发生了改变,比如屏幕发生旋转
screenSize 当屏幕的尺寸发生了改变,当屏幕进行旋转时,屏幕尺寸会发生改变,当minSdkVersion 和maxSdkVersion均低于13时不会发生Activity的重启,否则会发生Activity重启

一般常用的就是 android:configChanges="screenSize|keyboardHidden|orientation"这三个属性

3注意点

以下是几个需要注意的知识点:
(1)onStart和onStop,onPause和onResume,onCreate和onDestory是成对出现的
(2)onStart和onResume,onPause和onStop在实际使用上并没有什么本质上的区别,区别仅在于onStart和onStop是站在页面是否可见的角度上,而onResume和onPause则站在是否是前台Activity的角度上。
(3)当打开另一个Activity时会先调用当前的onPause方法在调用另一个Activity的onResume。

就先到这里吧。。。。。。

上一篇下一篇

猜你喜欢

热点阅读