Android四大组件之Activity
Activity是啥?
简单来说就是用来和用户交互的界面,由各个控件组成 ,将内容界面化展现于用户面前,接收用户的触摸事件和用户进行交互,可以说是使用最频繁的组件了。
Activity生命周期
生命周期: onCreate -> onStart -> onResume ->onPause -> onStop-> onDestroy 以及 onRestart 方法
一个Activity从创建到销毁的生命周期流程如下:
开启一个界面
2019-01-26 15:36:04.134 30064-30064/com.sjc.myapplication I/生命周期-----MainActivity: onCreate:
2019-01-26 15:36:04.207 30064-30064/com.sjc.myapplication I/生命周期-----MainActivity: onStart:
2019-01-26 15:36:04.221 30064-30064/com.sjc.myapplication I/生命周期-----MainActivity: onResume:
按下返回键
2019-01-26 15:36:12.381 30064-30064/com.sjc.myapplication I/生命周期-----MainActivity: onPause:
2019-01-26 15:36:12.943 30064-30064/com.sjc.myapplication I/生命周期-----MainActivity: onStop:
2019-01-26 15:36:12.944 30064-30064/com.sjc.myapplication I/生命周期-----MainActivity: onDestroy:
- onCreate 界面被创建,我们一般在这里进行一些视图和数据以及响应事件的初始化工作。(initView(),initData(),initAction())
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
initView();
initData();
initAction();
}
private void initView(){};
private void initData(){};
private void initAction(){};
- onStart 界面可见,此时界面还不可交互。
- onResume 界面可以进行交互,比如触发一些点击事件。
- onPause 界面失去交互,此时不可以进行交互。常见的导致该生命周期的执行的行为可能是:用户按下Home键、按下back键、跳转到下一个页面、弹出一个Dialog,或者PopupWindow等。此时我们可以做一些存储数据和停止动画等,但是不能太耗时,否则会影响下个页面的跳转(页面与页面之前跳转,先执行当前页面的onPause方法,然后执行下一个页面的 生命周期,具体执行下面有说明)。
- onStop 界面完全不可见的时候调用。两个Activity跳转,前一个Activity的onStop执行是在第二个Activity完全可见并可以进行交互后执行的(onCreate,onStart,onResume)
- onDestroy 界面被销毁,一般我们在这里做一些资源释放的操作,比如注销广播,关闭弹窗(如果页面被销毁,弹窗未被关闭,则会造成窗体泄漏),关闭动画等。
- onRestart 界面重新可见,从一个页面返回上一个页面,首先会调用上一个页面的 onRestart 方法,其次调用上一个页面的 onStart、onResume方法
两个页面进行跳转,ActivityA --> ActivityB 再从ActivityB按下返回键返回到ActivityA,其调用的生命周期方法为:
- 首先启动 ActivityA:
2019-02-18 23:08:28.362 4980-4980/com.sjc.myapplication I/生命周期-----ActivityA: onCreate:
2019-02-18 23:08:28.388 4980-4980/com.sjc.myapplication I/生命周期-----ActivityA: onStart:
2019-02-18 23:08:28.390 4980-4980/com.sjc.myapplication I/生命周期-----ActivityA: onResume:
- 在 ActivityA 中启动 ActivityB
2019-02-18 23:08:33.347 4980-4980/com.sjc.myapplication I/生命周期-----ActivityA: onPause:
2019-02-18 23:08:33.371 4980-4980/com.sjc.myapplication I/生命周期-----ActivityB: onCreate:
2019-02-18 23:08:33.393 4980-4980/com.sjc.myapplication I/生命周期-----ActivityB: onStart:
2019-02-18 23:08:33.395 4980-4980/com.sjc.myapplication I/生命周期-----ActivityB: onResume:
2019-02-18 23:08:33.819 4980-4980/com.sjc.myapplication I/生命周期-----ActivityA: onStop:
- 在 ActivityB 中按下返回键
2019-02-18 23:10:59.457 4980-4980/com.sjc.myapplication I/生命周期-----ActivityB: onPause:
2019-02-18 23:10:59.482 4980-4980/com.sjc.myapplication I/生命周期-----ActivityA: onRestart:
2019-02-18 23:10:59.482 4980-4980/com.sjc.myapplication I/生命周期-----ActivityA: onStart:
2019-02-18 23:10:59.483 4980-4980/com.sjc.myapplication I/生命周期-----ActivityA: onResume:
2019-02-18 23:10:59.813 4980-4980/com.sjc.myapplication I/生命周期-----ActivityB: onStop:
2019-02-18 23:10:59.814 4980-4980/com.sjc.myapplication I/生命周期-----ActivityB: onDestroy:
Activity销毁时保存数据
Activity 异常销毁的时候,会调用 onSaveInstanceState 方法保存数据,该方法是在 onStop 之前执行,我们可以使用 Bundle 来储存数据,当 Activity 重建的时候会调用 onRestoreInstanceState 方法,我们可以通过 onRestoreInstanceState(Bundle savedInstanceState)传递过来的Bundle来获取之前储存的数据。进行数据恢复。当然也可以在onCreate(Bundle savedInstanceState)方法里面取出来。
另:onSaveInstanceState 和 onRestoreInstanceState 方法中,系统自动为我们做了一些操作: 例如:Edittext 自动还原填写内容, ListView 还原滚动位置,因为每一个View都有自己的 onSaveInstanceState 和 onRestoreInstanceState 方法。
activity异常销毁的场景:
- 1.屏幕旋转会导致Activity重建(可以通过设置 android : configChanges = “orientation” 来防止Activity重建,还可以通过设置 android:screenOrientation=“portrait” 锁定Activity方向)
- 2.内存吃紧,导致优先级低的Activity被回收掉。
Activity 的四种状态:
- running:处于前台,和用户进行直接的交互。(系统最不愿意回收)
- Paused: 仍然可见,但是不可以交互。(系统不愿意回收)
- Stoped: 不可见,处于后台。(内存吃紧的时候,有可能会被回收)
- Killed: 被杀死,已经从Activity栈中移除。(系统倾向于回收这种 Activity)
Activity四种启动模式:
通过在 mainfest 里面的 android:launchMode= ""属性来设置
- standard 标准模式,如果不设置启动模式,Android 系统会默认将启动模式设置为该属性。每启动一次 Activity 就会创建一个实例压入栈中(连续启动两个一样的 Activity ,会创建两个实例,按照先后顺序压入栈中)。
- singleTop 在创建实例的时候,首先会查找任务栈栈顶是否有该 Activity 的实例存在,如果有就不再创建新的实例,直接使用栈中的实例。此时不会走 Activity 的 onCreate、onStart 生命周期方法,直接走 onPause–> onNewIntent --> onResume 方法。
- singleTask 在创建实例的时候,首先查找任务栈栈中是否有该实例的存在,如果有就不重新创建,直接将该实例的上面的所有实例(Activity)移除(Finish),也是不会走 Activity 的 onCreate、onStart 生命周期方法,直接走 onPause–> onNewIntent --> onResume 方法。
- singleInstance 直接为该Activity在整个Android系统中创建一个单独的任务栈(如果已经创建过,就不再重新创建),第一次创建时会走正常的生命周期流程,第二次直接走 onPause–> onNewIntent --> onResume 方法。
关于 taskAffinity 属性(可以指定Activity所在的任务栈),在 launchMode 为 standard 和 singleTop 的时候是没有作用的。具体作用体现在 singleTask 属性上。
具体详情链接 彻底弄懂Activity四大启动模式
Activity任务栈:
- 栈是一个常用的数据结构,栈的特点是先进后出,队列是先进先出
- Activity 是采用栈的数据结构进行管理的,最先打开的 Activity 最后退出。
- 打开一个应用的时候系统会默认分配一个任务栈,当所有 Activity 都退出时,栈就清空了。
- 在 Android 操作系统中是有多个任务栈的,一般一个应用对应一个任务栈。
- 默认情况下,关闭一个应用,就清空这个这个应用的任务栈,但是这个应用的进程还在。