本人是已经参加工作大半年的菜鸟一枚,为公司也做了两个项目,学习到了不少知识,但是感觉自己的基础不是很足,也需要一些进级,所以就买了任玉刚大神的android开发艺术探索来学习,查漏补缺,多多学习,不管是我知道的还是我不知道的我都要重新查漏补缺。
站在巨人的肩膀上我能看的更远,由于公司有开发新项目,时间只能在空余时间挤,所以我决定把这本书看完,并且在csdn上留下自己的学习笔记。
第一章 Activity的生命周期和启动模式
1.1.1典型情况下的生命周期
onCreate 创建,可做一些初始化工作比如:加载界面布局初始化Activity所需数据,
onRestart 第一次启动不会触发,只有当activity没有销毁时,当activity重新启动时,从不可见变成可见,一般是用户操作产生 比如说回到桌面再回到当前activity
onStart 表示activity已经被创建并且正在启动,当前是可见状态,但是还在后台,无法进行交互
onResume 表示Activity已经可见并且出现在前台,可以进行用户交互
注:onStart onResume 都可以理解为可见状态但是onstart实在后台,不可以进行用户交互,onResume 才会到前台工作
onPause 表示Activity正在停止,尽量不要再此时做耗时操作,因为会影响到新activity的现实
onStop 表示Activity即将停止,尽量不要再此时做耗时操作
onDestory 表示Activity将要被销毁,可以做回收和资源释放
用户创建 onCreate——onStart——onRestume
用户打开新activity 执行(ActivityA到ActivityB) onpause——oncreate——onstart——onresume——第一个activity的onstop
所以在onpause和onstop中不可以做重量级操作,因为ActivityB要尽快现实并切换到前台
当用户再次回到原activity onRestart——onStart——onRestume
按下back键onPause——onstop——onDestory
1.1.2 异常情况下的声明分析
1: 相关资源的的系统配置发生改变导致activity被杀死并重新创建
举个栗子: 一个Activity调用了drawable中的图片 这个时候手机本来是横屏的,突然变为竖屏,在默认情况下Activity就会被销毁重新创建
这个时候Activity就会在onStop之前调用OnSaveInstanceState方法报留当前activity的状态
当Activity被重新创建时系统在onStart之后会默认调用OnRestoreInstantceState来获取OnSaveInstanceState所保存的Bundle对象,同时,系统会在恢复的时候恢复一些数据,比如说Editext中的数据Recyclerview、Listview滚动的位置
保存和恢复view的层次结构和view的创建过程是一样的,都是委托关系,子view委托父view
首先调用onSaveinstaceState保存数据然后activity委托window,window委托他上记得容器,恢复的过程就是倒过来
在恢复数据的时候我们可以在Oncreate中获取也可以在OnRestoreinStanceStant中获取,但是两者的区别是OnRestoreinStanceStant里边的值是一定有价值的不用判断==null,而OnCreate中却一定要判断OnSaveInstanceState==null,官方也是推荐我们在OnRestoreinStanceStant中恢复数据
同时注意一点OnSaveInstanceState OnRestoreinStanceStant只会在activity异常关闭并且有机会重新现实的时候才会调用,正常销毁的时候不会调用,比如首屏幕旋转异常销毁
当然Activity既然会因为我们改变了系统的一些配置而重新启动了,那么我们还可以在此时不让Activity进行重新启动
防止再次调用onCreate,首先设置权限
其次需要设置android:configChanges,可选属性如下:
Value | Description |
“mcc“ | The IMSI mobile country code (MCC) has changed — that is, a SIM hasbeen detected and updated the MCC.移动国家号码,由三位数字组成,每个国家都有自己独立的MCC,可以识别手机用户所属国家。 |
“mnc“ | The IMSI mobile network code (MNC) has changed — that is, a SIM hasbeen detected and updated the MNC.移动网号,在一个国家或者地区中,用于区分手机用户的服务商。 |
“locale“ | The locale has changed — for example, the user has selected a new language that text should be displayed in.用户所在地区发生变化。语言 |
“touchscreen“ | The touchscreen has changed. (This should never normally happen.)可忽略 |
“keyboard“ | The keyboard type has changed — for example, the user has plugged in an external keyboard.键盘模式发生变化,例如:用户接入外部键盘输入。 |
“keyboardHidden“ | The keyboard accessibility has changed — for example, the user has slid the keyboard out to expose it.用户打开手机硬件键盘 |
“navigation“ | The navigation type has changed. (This should never normally happen.) |
“orientation“ | The screen orientation has changed — that is, the user has rotated the device.设备旋转,横向显示和竖向显示模式切换。 |
“fontScale“ | The font scaling factor has changed — that is, the user has selected a new global font size.全局字体大小缩放发生改变 |
比如:不让屏幕转动你的api大于了13你要设置android:configChanges=“orientation|screenSize”
当然你也可以在AndroidManifest.xml的activity(需要禁止转向的activity)配置中加入 android:screenOrientation=”landscape”属性即可(landscape是横向,portrait是纵向)来强制不让activity转动。
2:资源内存不足导致低优先级的Activity被杀死
Activity的优先级一般可以分为种:
(1)前台Activity正在和用户交互的Activity优先级最高。
(2)可见但是非前台Activity比如:当前Activity唤起了一个dialog导致activity非可见无法和用户直接交互
(3)后台Activity 意见呗暂停执行了onstop优先级最低
当系统内存不足时,系统会按照以上优先级去杀死目标Activity所在的进程并且使用onSaveInstanceState和onRestoreInstance来储存和恢复数据,如果一个进程没有四大组件执行,那么他会很快被系统杀死,所以后台的工作最好放到service中,就不会被轻易的杀死。
1.2 Activity的启动模式
我们再创建同一个Activity时系统会创建多个实例把他们放入任务栈中 任务栈采用 后进先出 模式 android有四种启动模式
1:standard标准模式
(1)每启动Activity都会重新创建一个实例,并且不管这个实例是否存在
(2)谁启动了这个Activity那么这个Activity就会在被启动的Activity所在栈中
比如:如果ActivityB是标准模式被ActivityA所启动,那么ActivityB就会被加入到ActivityA所在的栈内。
2:singleTop栈顶复用模式
(1)如果一个Activity位于任务栈的栈顶,那么此activity不会被重新创建,并调用OnNewIntnet
(2)如果已经存在但是不是位于栈顶,那么还是会重新创建
举个栗子:ABCD四个Activity A位于栈底,D位于栈顶且模式为singleTop,这个时候要重新启动D那么栈内情况是ABCD
D位于栈顶且模式为standard 那么重新启动D 栈内情况为ABCDD
3:singleTask栈内复用模式
(1)只要Activity在一个栈内存在,那么多次启动此activity都不会重新创建实例 并调用OnNewIntnet
举个栗子:
1:栈S1中为ActivityABC 这个时候D以singleTask 启动其所要的栈为s2 D和s2都不存在,系统会先创建S2,然后在创 建D将实例入栈到S2
2: 假如D所需要的栈是S1那么系统会直接创建D并且入栈到S1
3:假如D所需的栈为s1 当前栈内为ADBC,那么D不会被重新创建,而会被切换到栈顶调用OnNewIntent,同时SingleTask具有clearTop,会导致之前在D上面的Activity全部出栈变为AD
4 :SingleInStance单实例模式
加强的singletask 有singletask的所有属性 并且此模式下的Activity会在一个单独的栈内
举个栗子:当A时此模式,那么创建时系统会先创建一个此模式的新栈,然后A入栈