Activity的生命周期

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~

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值