第1章:Activity的生命周期和启动模式
1.1Activity的生命周期全面解析
1.1.1典型情况下的生命周期
从Activity整个生命周期来说,onCreate和onDestroy是配对的,分别标志着Activity的创建和销毁,并且只可能有一次调用,从Activity是否可见来说,onStart与onStop是配对的,随着用户的操作或者屏幕的点亮和熄灭,这两个方法可能被调用多次;从Activity是否在前台来说,onResume与onPause是配对的,随着屏幕的点亮和熄灭,这两个方法可能被调用多次.
问题1:onStart和onResume,onPause和onStop从描述上来看差不多,对我们来说有什么本质的不同那?
onStart和onStop是从Activity是否可见这个角度进行回调的,而onResume和onPause是从Activity是否位于前台这个角度进行回调的,在实际的应用中除了这两个区别,没有其他明显的区别.
问题2:假设当前Activity为A,如果这时用户打开了一个新的Activity B,那么B的onResume和A的onPause哪个先执行?
通过测试及源码分析得出:A Activity onPause--->B Activity onCreat-->B Activity onStart -->B Activity onResume --->A Activity onStop
从另一个角度分析,onPause与onStop都不能执行耗时操作,尤其是onPause,这也意味着尽量在onStop中做操作,从而使Activity尽快的显示出来,并切换到前台.
1.1.2异常情况下的生命周期分析
情况1:资源相关的系统配置发生改变,导致Activity被杀死并且重建
当系统配置发生改变后,Activity会被销毁,onPause,onStop,onDestroy都会被调用,由于Activity是在异常情况下终止的,系统会调用onSaveInstanceState来保存当前Activity的状态.这个方法调用的时机是在onStop之前,它和onPause没有既定的时序关系.当Activity重建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法,因此我们可以通过onRestoreInstanceState和onCreate方法来判断Activity是否被重建了,如果被重建了,那么我们就可以取出之前的数据进行数据恢复,从时序上来说,onRestoreInstanceState的调用时机在onStart之后.
情况2:资源内存不足导致低优先级的Activity被杀死
Activity的优先级顺序从高到低:
(1)前台Activity---正在和用户交互的Activity,优先级最高.
(2)可见非前台Activity---比如Activity中弹出了一个对话框,导致Activity可见但是位于后台无法和用户进行交互.
(3)后台Activity----已经被暂停的Activity,比如执行了onStop,优先级最低.
当系统内存不足时,会按上述优先级去杀死目标Activity所在的进程,并在onSaveInstanceState和onRestoreInstanceState保存和恢复数据.如果一个进程中没有四大组件在运行,这个进程将很快被系统杀死.因此一些后台操作不适合脱离四大组件独立运行.
当系统的某项某项配置发生改变时,可以通过设置Activity的configChanges,来防止Activity的重建.
1.2Activity的启动模式
1.2.1Activity的LaunchMode
Activity的四种启动模式:
(1)standard,即标准模式,也是默认模式.当用ApplicationContext去启动standard模式会报错,是因为非Activity的Context并没有所谓的任务栈,只需要在启动Activity的时候指定FLAG_ACTIVITY_NEW_TASK标记位,这样在启动的时候会创建一个新的任务栈.这时候启动的Activity实际上是以singleTask模式启动的.
(2)singleTop:栈顶复用模式.如果Activity已经位于任务栈的栈顶,那么Activity不会被重建,直接回调onNewIntent方法,如果新的Activity已经存在,但不是位于栈顶,那么Activity仍然会被重建.
(3)singleTask:栈内复用模式.当一个具有singTask模式的Activity A请求启动后,系统首先会寻找它所需要的任务栈,如果没有该任务栈,系统首先会进行创建一个任务栈,然后把Activity A放进去.如果有任务栈,就去判断Activity A的实例是否存在栈中,如果没A的实例不存在,就创建A的实例压入栈中,如果存在,系统就把A调到栈顶且默认具有clearTop的效果并调用它的onNewIntent方法.
(4)singleInstance:单实例模式.这是一种加强版的singleTask模式,它具有singleTask模式的所有的特性之外,还有一个特性:具有这种模式的Activity只能单独位于一个任务栈中
Activity所需要的任务栈
默认情况下所有Activity所需要的任务栈的名字为应用的包名.同样,我们可以为通过TaskAffinity属性来为每个Activity指定任务栈的名字.TaskAffinity属性值是字符串,且中间必须含有包名分隔符"."TaskAffinity属性主要和singleTask启动模式或者allowTaskReparenting属性配合使用,其他情况下没有意义.另外,任务栈分为前台任务栈和后台任务栈,后台任务栈的Activity处于暂停状态,用户可以通过切换再次将后台任务栈切换到前台.
1.3IntentFilter的匹配规则
只有一个Intent同时匹配action类别,category类别,data类别才算完全匹配,只有完全匹配才能启动目标Activity,一个Activity中可以有多个intent-filter,一个Intent只要能匹配任意一组intent-filter即可成功启动对应的Activity.
1.action的匹配规则
action是一个字符串,区分大小写,action的匹配要求Intent中的action存在且必须和过滤条件中的任意一个action相同.
2.category的匹配原则
category是一个字符串,它要求intent如果有category,则必须与过滤规则中的任意一个category相同,未设置category时,系统在调用startActivity或者startActivityForResult的会默认为这个intent添加"android.intent.category.DEFAULT"这个category.
3.data的匹配原则
data的匹配规则和action的匹配规则比较相似,如果过滤则中定义了data,那么intent中也必须要定义可匹配的data.
第2章:IPC机制
2.1:Android IPC机制简介
IPC:Inter-Process Communication的缩写,即进程间通信也可以称之为跨进程通信.
IPC机制的使用场景
情况1:比如有些模块因为特殊的原因需要运行在单独的进程中,或者为了加大一个应用可使用的内存所以通过多进程来获取多份内存空间.
情况2:当前应用需要向其他应用获取数据,由于是两个应用,所以必须采用跨进程的方式来获取所需数据,通过系统提供的ContentProvider去查询数据的时候,其实也是一种跨进程通信.
2.2:Android中多进程模式
2.2.1:开启多进程模式
Android中使用多进程只有一种方法:在Menifest中给四大组件指定android:process属性.也就是说无法为一个线程或一个实体类指定其运行时所在的线程.其实还有一个非常规的方法,就是通过JNI在native层fork一个新的进程.进程名以":"开头的进程属于当前应用的私有进程,其他应用的组件不可以和它跑在一个进程中,而进程名不以":"开头的进程属于全局进程,其他应用通过SharedUID的方式可以和它跑在同一个进程中.
2.2.2:多进程模式的运行机制
多进程带来的影响:所有运行在不同进程的四大组件,只要他们之间需要通过内存来共享数据,都会共享失败.
一般情况下,使用多进程会造成如下几个方面的问题:
(1)静态成员和单例模式完全失效.
(2)线程同步机制完全失效.
(3)SharedPreferences的可靠性下降.
(4)Application会多次创建.
2.3:IPC基础概念
2.3.2Parcelable接口
系统提供的实现序列化接口的类:Intent、Bundle、Bitmap、List、Map,但前提是他们里面的每个元素都是可序列化的。
Parcelable与Serializable的区别:
Serializable是java中的序列化接口,使用简单但开销大,序列化和反序列化需要大量的I/O操作。适用于将对象序列化到存储设备中或将对象序列化后用于网络传输。
Parcelable是Android的序列化方式,更适合在Android平台上使用,缺点是使用麻烦,但效率高。主要用于内存序列化。
2.4:Android中的IPC方式
(1)使用Intent传递数据
(2)使用文件共享和SharedPreferences
(3)基于Binder的Messenger和AIDL
(4)使用Socket
2.4:Android中的IPC方式
第8章:理解Window和WindowManager
WindowManager是外界访问Window的入口,Window的具体实现位于WindowManagerService中,WindowManager与WindowManagerService的交互是一个IPC过程,Android中所有的视图都是通过Window来呈现的,包括Activity,Dialog,Toast等。
事件的传递顺序:Window----->DecorView------>View
8.1:Android IPC机制简介
WindowManager.LayoutParams.flags
FLAG_NOT_FOCUSABLE:表示Window不需要获取焦点,也不需要接收各种事件
FLAG_NOT_TOUCH_MODAL:表示将当前Window区域以外的事件往下传递,Window区域以内的事件自己处理。
FLAG_SHOW_WHEN_LOCK:可以让Window显示在锁屏界面上。
WindowManager.LayoutParams.type:
应用Window:对于一个Activity,层级范围:1~99
子Window:不能单独存在,需要附属在特定的父Window之中,层级范围:1000~1999,如:Dialog
系统Window:需声明权限,层级范围:2000~2999,如Toast、状态栏