I.何为Activity?
是Android的四大组件中最直观的一个,可以狭义地理解为Activity是与用户交互的界面,可以处理与用户交互的事件。简单说就是看到的界面。
常见的 Activity 类型有 ListActivity,FragmentActivitiy,TabAcitivty 等。当然开发中可根据自己的功能设计自己的公共基类: BaseActivity。
II.Activity的生命历程——概览
官方文档中对Activity的生命周期有个比较经典图,如下图一所示:
图一
由图一可以看出,Activity的一般操作的生命周期如下:
1. Activity正常启动:onCreate()->onStart()->onResume() // 上图中主流程的上半部分
2. Acivity正常退出:onPause()->onStop()->onDestory() // 上图中主流程的下半部分
3.Activity A 启动另一个Activity B(A还未被Destroy),A的流程: onPause()->onStop() // 上图中主流程的下部分
再返回时,A的流程:onRestart()->onStart()->onResume() // 上图中右侧枝
4. Activity按Back 退出: onPause()->onStop()->onDestory() // 上图中主流程的下半部分,退出时finish了or被系统清理掉了
再进入:onCreate()->onStart()->onResume() // 上图中主流程的上半部分
5. Activity按Home 退出: onPause()->onStop() // 上图中主流程的下半部分,退出后没有被系统清理掉
再进入:onRestart()->onStart()->onResume() // 上图中右侧枝
6. 在当前Activity前显示系统的提示框or自定义提示信息(该提示信息显示时原来的Acitity可见),再Back返回:
onPause()->onResume() // 上图中右侧枝
简单总结:
》》Activity有如下特点:
A、在OnCreate创建,在OnDestroy销毁;
B、在onStart()之后可见,onStop之后不可见;
C、在OnResume之后获得焦点,在OnPause之后失去焦点。
D、在不可见时,如果系统资源紧张,会自动将Activity Destroy,再次拉起Activity时,需要重建则走OnCreate,否则走OnRestart ->OnStart。
E、因此,在开发中可以将一些必要资源释放放在onDestory中进行,而只需要在重建时更新设置的处理放在OnCreate中进行,需要每次切换页面显示时更新的处理放在OnResume,当然要注意他们之间的配合,不然会出错哦。
III.半截的人生————意外的生命周期
上面是正常的生命周期,在具体使用中可以根据具体需要自行设计,从而会出现不同的生命周期。
1. 什么情况下Activity走了onCreat(),而不走onStart()?
比如,之前有网友总结的与Activity生命周期有关的一个面试题:
什么情况下Activity走了onCreat(),而不走onStart()?
可能好多朋友乍一听到这个题就被砸了个晕头转向,可仔细一分析就会发现在开发中都用过,只是没有仔细考虑所谓的生命周期而已。
比如说,Activity B启动时需要从拉起他的Activity A提供的Intent中读取数据,如果这个关键数据没有就无法显示 or 逻辑性强或有强迫症的兄弟,会顺手先判断下这个Intent是否为空,就像下面这样:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_xxx);
Intent intent = getIntent();
if (null != intent) {
userName = intent.getStringExtra(USER_NAME);
ipStr = intent.getStringExtra(HOST_IP);
} else {
Log.e(TAG, "intent is null, can not get username!!");
finish();
}
.....
}
如果为空,干啥? 当然是直接Finsih了。
不Finish还干嘛,等着找抽被提Bug么,嘿嘿
好了,答案就是这个:
当Activity在OnCreate中直接退出时 or 被迫中断时(比如挂了),会直接onCreate -> onDestroy,而不会执行onStart。
个人觉得这个问题没啥意思,纯粹是几角旮旯的玩意儿,但同志们还需谨慎呐,生活不易。。。
2. 何时调用OnRestart?
由图一可以看出,当处于OnStop状态(但还没有被 onDestroy)的Activity被拉到前台时,会走OnRestart->onStart->onResume,无需走OnCreate重建,因为还未被Destroy掉。
3. 什么情况下OnStop可能永远不会被调用?
根据官方文档:当系统处于低内存状态下,没有足够的内存保持Activity的OnPause之后的处理时,会不调用OnStop。
恩,另一个意思就是,即使是低内存状态下,也是会调用OnPause滴。
在Activity退出时需要处理的东西,要放在那里进行,有数了吧,最好不要用OnStop,不靠谱~
4. onResume与onWindowFocusChanged一样么?
一般情况面试问这样的问题,答案都是 不一样,这是一般哈。
这里就是一般,嘿嘿
前面说OnResume之后Activity可见,能获取焦点,同样onWindowFocusChanged也与焦点有关,当前显示Activity的窗口获得或失去焦点的时候会调用onWindowFocusChanged。
官方文档中是这样描述的:
当前Activity的窗口获得或失去焦点的时候会调用。
这个函数,对于判断Activity是否对用户可见来说,是最好的方向标,它默认的实现是清除键跟踪状态,所以应该总是被调用。
它也提供了全局的焦点状态,其管理独立于activity生命周期。当焦点改变时一般都伴随着生命周期的改变,你不应该依赖onWindowFocusChanged 调用和其他生命周期的方法(例如onResume) 的先后顺序,来处理我们要做的事情。
通常的规则是,当一个Activity被唤醒,那么就拥有窗口焦点。除非这个窗口已经显示了对话框或者其他弹出框抢占焦点,这个窗口只有等到这些对话框关闭后,才能获取焦点,同理,当系统显示系统级的窗口,系统级的窗口会临时的获取窗口输入焦点同时不会暂停前景 activity。
大多数情况下只要调用了onResume 就会调用 onWindowFocusChanged,也有例外,比如下拉系统菜单的时候只会调用onWindowFocusChanged。
一句话,判断焦点,用onWindowFocusChanged比较靠谱。
例如:我们在下拉菜单中改变了网络的状态(开启或者关闭),这时候就不能在onResume()中处理更新网络状态,而应该将更新网络状态放到onWindowFocusChanged中处理。
5. onStart()和onResume()有啥区别?
在onStart中,视图不可见,在onResume中,视图可见;前者属于可见进程,后者属于前台进程。至于可见进程与前台进程还是去问度娘吧哈
6. 烦躁的横竖屏切换
横竖屏切换时,生命周期的表现根据Manifest的配置不同而不同,而且在模拟器与真机上表现也不同, 咱们一起理理……
1)Manifest配置的影响
Manifest中对应Activity 的 android:configChanges 属性设置,会影响生命周期:
- 不设置 android:configChanges 时,横竖屏切换时,会重新调用各个生命周期。 默认首先销毁当前 Activity,然后再重新加载, 如下图所示:
- 设置 android:configChanges=”orientation|screenSize“时(两个都要设置),横竖屏切换时,不会重新调用各个生命周期,只执行 onConfigurationChanged 方法。
- 如果设置Activity固定为横屏或竖屏,就不存在横竖屏切换的问题,也不会存在生命周期切换的问题。固定横竖屏的属性为android:screenOrientation
- 当然,如果同时配置了上述两个属性(android:screenOrientation,android:configChanges=”orientation”)则后者失效,不存在横竖屏切换。
2)真机与模拟器的影响
真机与模拟器差别较大:
- 如果不配置android:configChanges属性 or 该属性配置为orientation,则切到横屏时,模拟器中执行一次销毁->重建,切到竖屏执行两次,而真机均为一次。
- 如果配置android:configChanges=”orientation|keyboardHidden”,模拟器中切到横屏执行一次onConfigurationChanged,切竖屏执行两次,而真机均为一次。
这个其实意义不大,知道就行,啥时候需要做横竖屏切换时,注意一下就行了。
恩,暂时就想到这些,想起来再追加ba~