共计 3682 个字符,预计需要花费 10 分钟才能阅读完成。
读前思考
学习一门技术或者看一篇文章最好的形式就是带着问题去学习,这样能力在过程中有茅塞顿开、灯火阑珊的感觉,记忆也会更粗浅。
- 说下 Activity 的生命周期?
- Activity A 启动另一个 Activity B 会回调哪些办法?如果 Activity B 是齐全通明呢?如果启动的是一个 Dialog 呢?
- 谈谈 onSaveInstanceState() 办法?何时会调用?
- 如何防止配置扭转时 Activity 重建?
- 优先级低的 Activity 在内存不足被回收后怎么做能够复原到销毁前状态?
- 说下 Activity 的四种启动模式?别离会在什么时候应用?
- onNewIntent()调用机会?
- 如何启动其余利用的 Activity?
Activity 生命周期
onCreate() -> onStart() – > onResume() -> onPause() -> onStop() -> onDestroy()
- onCreate(): 在流动第一次被创立时会调用,能够在这个办法中实现初始化操作,如:布局加载、绑定事件等。
- onStart(): 在流动由不可见变为可见时候调用。
- onResume(): 在返回栈顶端,取得焦点,能够和用户进行交互。
- onPause: 失去焦点,零碎去启动另一个流动时候会调用,能够在这里做一些数据保留,资源开释,但不能做耗时操作。
- onStop: 流动齐全不可见时调用。
- onDestroy: 流动被销毁时调用。
- onRestart: 流动由后盾不可见变为前台可见时候调用。
启动 Activity
A 启动 B
重写 A 和 B 的生命周期办法
A 启动 B
com.keven.jianshu E/TAG: A 的 onPause()
com.keven.jianshu E/TAG: B 的 onCreate()
com.keven.jianshu E/TAG: B 的 onStart()
com.keven.jianshu E/TAG: B 的 onResume()
com.keven.jianshu E/TAG: A 的 onStop()
从 B 返回 A
com.keven.jianshu E/TAG: B 的 onPause()
com.keven.jianshu E/TAG: A 的 onRestart()
com.keven.jianshu E/TAG: A 的 onStart()
com.keven.jianshu E/TAG: A 的 onResume()
com.keven.jianshu E/TAG: B 的 onStop()
com.keven.jianshu E/TAG: B 的 onDestroy()
A 启动通明的 B (或者 Dialog 模式)
com.keven.jianshu E/TAG: A 的 onPause()
com.keven.jianshu E/TAG: B 的 onCreate()
com.keven.jianshu E/TAG: B 的 onStart()
com.keven.jianshu E/TAG: B 的 onResume()
onSaveInstanceState
异常情况下的生命周期:比方当零碎资源配置产生扭转以及零碎内存不足时,activity 就可能被杀死或者销毁后重建。
1. Activity 横竖屏切换
com.keven.jianshu E/TAG: A 的 onCreate()
com.keven.jianshu E/TAG: A 的 onCreate() 中 savedInstanceState 是空的吗?true
com.keven.jianshu E/TAG: A 的 onStart()
com.keven.jianshu E/TAG: A 的 onResume()
com.keven.jianshu E/TAG: A 的 onPause()
com.keven.jianshu E/TAG: A 的 onStop()
com.keven.jianshu E/TAG: A 的 onSaveInstanceState()
com.keven.jianshu E/TAG: A 的 onDestroy()
com.keven.jianshu E/TAG: A 的 onCreate()
com.keven.jianshu E/TAG: A 的 onCreate() 中 savedInstanceState 是空的吗?false
com.keven.jianshu E/TAG: A 的 onStart()
com.keven.jianshu E/TAG: A 的 onRestoreInstanceState()
com.keven.jianshu E/TAG: A 的 onResume()
能够看到横竖屏切换时,会调用 onSaveInstanceState()进行状态保留,再次创立时,会调用 onRestoreInstanceState() 办法进行数据的复原。
解决办法:
能够通过在清单文件中设置如下属性,防止横竖屏切换时从新创立。
android:configChanges="orientation|screenSize"
2、内存不足时
资源内存不足导致低优先级的 activity 被杀死
这里的状况和后面横竖屏切换的数据存储和复原是完全一致的,activity 依照优先级从高到低能够分为如下三种:
- 前台 activity:正在和用户交互的 activity,优先级最高
- 可见但非前台 activity,比方 activity 中弹出了一个对话框,导致 activity 可见然而位于后盾无奈和用户间接交互。
- 后盾 activity,曾经被暂停的 activity,比方执行了 onStop,优先级最低。
启动模式
standard- 默认模式
这个模式是默认的启动模式,即规范模式,在不指定启动模式的前提下,零碎默认应用该模式启动 Activity,每次启动一个 Activity 都会重写创立一个新的实例,不论这个实例存不存在,这种模式下,谁启动了该模式的 Activity,该 Activity 就属于启动它的 Activity 的工作栈中。
singleTop- 栈顶复用模式
这个模式下,如果新的 activity 曾经位于栈顶,那么这个 Activity 不会被重写创立,同时它的 onNewIntent 办法会被调用,通过此办法的参数咱们能够去除以后申请的信息。如果栈顶不存在该 Activity 的实例,则状况与 standard 模式雷同。须要留神的是这个 Activity 它的 onCreate(),onStart() 办法不会被调用,因为它并没有产生扭转。
singleTask- 栈内复用模式
在这个模式下,如果栈中存在这个 Activity 的实例就会复用这个 Activity,不论它是否位于栈顶,复用时,会将它下面的 Activity 全副出栈,并且会回调该实例的 onNewIntent 办法。其实这个过程还存在一个工作栈的匹配,因为这个模式启动时,会在本人须要的工作栈中寻找实例,这个工作栈就是通过 taskAffinity 属性指定。如果这个工作栈不存在,则会创立这个工作栈。
singleInstance- 全局惟一模式
该模式具备 singleTask 模式的所有个性外,与它的区别就是,这种模式下的 Activity 会独自占用一个 Task 栈,具备全局唯一性,即整个零碎中就这么一个实例,因为栈内复用的个性,后续的申请均不会创立新的 Activity 实例,除非这个非凡的工作栈被销毁了。以 singleInstance 模式启动的 Activity 在整个零碎中是单例的,如果在启动这样的 Activiyt 时,曾经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。
隐式启动
采纳隐式形式启动 Activity 时,能够用 PackageManager 的 resolveActivity 办法或者 Intent 的 resolveActivity 办法判断是否有 Activity 匹配该隐式 Intent。
IntentFilter 匹配规定:
- 一个 intent 只有同时匹配某个 Activity 的 intent-filter 中的 action、category、data 才算齐全匹配,能力启动该 Activity。
- 一个 Activity 能够有多个 intent-filter,一个 intent 只有胜利匹配任意一组 intent-filter,就能够启动该 Activity。
a. action 匹配规定:
要求 intent 中的 action 存在且必须和 intent-filter 中的其中一个 action 雷同。辨别大小写。
b. category 匹配规定:
intent 中的 category 能够不存在,这是因为此时零碎给该 Activity 默认加上了
< category android:name="android.intent.category.DEAFAULT" />
属性值。除上述情况外,有其余 category,则要求 intent 中的 category 和 intent-filter 中的所有 category 雷同。
c. data 匹配规定:
如果 intent-filter 中有定义 data,那么 Intent 中也必须也要定义 data。data 次要由 mimeType (媒体类型)和 URI 组成。在匹配时通过 intent.setDataAndType(Uri data, String type) 办法对 date 进行设置。