Android 面试(二):如何理解 Activity 的生命周期

这是说好的 面试系列 的第二期。本期我们依然来探讨一些面试必考题。

往期内容传递:
Android 面试:说说 Android 的四种启动模式

说说 Activity 的生命周期吧

当我告诉你面试官会问这个问题的时候,你一定是「啪」,给我一耳光。这样的问题网上一搜一大堆,随便背诵一下就可以轻松面过,有必要这么大费周折地来听「南尘」吹一波吗?

Android 面试(二):如何理解 Activity 的生命周期_第1张图片
nanchen

所以你开始背诵起来。

  • 启动 Activiy:onCreate => onStart() => onResume(), Activity 进入运行状态.
  • Activity 退居后台 ( Home 或启动新 Activity ): onPause() => onStop().
  • Activity 返回前台: onRestart() => onStart() => onResume().
  • Activity 后台期间内存不足情况下当再次启动会重新执行启动流程。
  • 锁屏: onPause() => onStop().
  • 解锁: onStart() => onResume().

干脆上张图,更清晰。


Android 面试(二):如何理解 Activity 的生命周期_第2张图片
nanchen

咋一看还是挺清晰的,对,能背下来,甚至能把图在心里记下来确实不错。

但但是!!!

现在的面试官还会这样问你吗?

会!

对初级甚至是入门的 Android 开发工程师吧?

Android 面试(二):如何理解 Activity 的生命周期_第3张图片
nanchen

不卖关子,那怎么问呢?

怎么问之前,我想分别解析下这些方法,帮助大家理解。注意其中我加粗的部分。

  • onCreate()
    每个活动中我们都重写了这个方法, 它会在活动第一次被创建的时候调用。 你应该在这个方法中完成活动的初始化操作, 比如说加载布局、绑定事件等。

  • onStart()
    这个方法在活动由不可见变为可见的时候调用。

  • onResume()
    这个方法在活动准备好和用户进行交互的时候调用。 此时的活动一定位于返回栈的栈顶,并且处于运行状态。

  • onPause()
    这个方法在系统准备去启动或者恢复另一个活动的时候调用。 我们通常会在这个方法中将一些及其消耗 CPU 的资源释放掉(比如显示地图或者大规模图形),以及保存一些关键数据(比如用户输入的数据等等),但这个方法的执行速度一定要快,不然会影响到新的栈顶活动的使用。

  • onStop()
    这个方法在活动完全不可见的时候调用。它和 onPause()方法的主要区别在于,如果启动的新活动是一个对话框式的活动,那么 onPause() 方法会得到执行,而 onStop()方法并不会执行。

  • onDestroy()
    这个方法在活动被销毁之前调用,之后活动的状态将变为销毁状态。

  • onRestart()
    这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重新启动了。

对官方代码感兴趣的童鞋可以去翻阅源码,其中 Activity 单 onXXX 的回调方法 API 就高达八十多种,单纯记忆下来根本没用。额,可能有用,你可以为你超强的记忆力感到骄傲和自豪!

上面的几种方法除了 onRestart() 以外,都两两相对,我们又可以分为三个时期。

  • 完整生存期
    活动在 onCreate()方法和 onDestroy() 方法之间所经历的,就是完整生存期。一般情况下,一个活动会在 onCreate() 方法中完成各种初始化操作,而在 onDestroy() 方法中完成释放内存的操作。

  • 可见生存期
    划重点!!!这个问题我就在面试中遇到了,其实我知晓这个题,怎奈误解了面试官的意思答非所问了。活动在 onStart() 方法和 onStop() 方法之间所经历的,就是可见生存期。在可见生存期内, 活动对于用户总是可见的, 即便有可能无法和用户进行交互。 我们可以通过这两个方法,合理地管理那些对用户可见的资源。比如在 onStart() 方法中对资源进行加载,而在 onStop() 方法中对资源进行释放, 从而保证处于停止状态的活动不会占用过多内存。

  • 前台生存期
    活动在 onResume() 方法和 onPause() 方法之间所经历的,就是前台生存期。在前台生存期内, 活动总是处于运行状态的, 此时的活动是可以和用户进行相互的, 我们平时看到和接触最多的也这个状态下的活动。

到底怎么问?

说了这么多,不妨我们可以模拟几种面试官的询问场景。

1、假设项目中有这样的需求,当指定的 Activity 在用户可见后才进行广播的注册,在用户不可见后对广播进行注销,那应该在哪两个回调中做这个处理呢?

2、如果有一些数据在 Activity 跳转时(或者离开时)要保存到数据库,那么你认为是在 onPause() 好还是在 onStop() 执行这个操作好呢?

3、Activity A 启动了 Activity B,简单说下它们分别的生命周期的变化。

4、Activity A 通过 Intent 显示启动了 Activity B,当 B 处于可见状态后,A 是否一定会调用 onStop()?

首先第一个问题,我们认真看了上面的解释的童鞋肯定都比较清楚。问题中强调了「可见」和「不可见」,所以我们只需要注重可见生命周期,在Activity 启动后,会先调用 onCreat() 方法进行布局和想关事件的绑定,直到回调 onStart() 方法后活动才可见,所以直接回答 onStart()onStop() 即可。

第二个问题,熟悉 Activity 的生命周期的我们都知道,onPause() 相比 onStop() 更容易触发。而「数据」就是 APP 甚至互联网产品的根,我们虽然绝大多数情况下都会遵从 onPause() => onStop() 的原则,但我们实在难以保证每次运行都能正常运行到 onStop() 方法,比如还没运行到 onStop() 系统就被回收了。

值得注意的是,这个操作要尽量地快,不然肯定会影响到下一个 Activity 的生命周期的。

第三个和第四个问题其实考察的点基本一致,大概就想考察面试者是否认为只要最上层栈顶的 Activity B 处于可见状态,那下面一层的 Activity A 就一定会调用 onStop() 方法。

如果直接照第四个问题的方式提问你,你就算认定一定会调用,但你也会被问的怀疑人生。但由于你觉得一定调用 onStop() 方法,并且你也找不到不调用的情况,所以你很耿直的回答了一定会调用。

实际上却并不是一定会调用,我们上面也说了,Activity 调用 onStop() 的时期是该 Activity 处于完全不可见状态,所以我们只需要想办法举出还可见的状态就好了。

我们假设弹出一个对话框形式的 Activity B,甚至就算弹出一个正常的 Activity B,把 B 的页面设置较低的透明度,实际上是一样的效果,不信你去打印日志试试。

上面提到了数据存储要放在 onPause() 比较好,那么无论什么数据的保存都放在 onPause() 可行吗?

哈哈,之前我也是认为是正确的,直到今天。

假设部分数据是非常重要的,我们需要在各种情况都要考虑到存储起来,我之前也是用 onPause() 生命周期做的处理。

可当我直接关闭电源,再重启的时候数据直接不见了!!!

想来也是应该的,直接关掉电源,谁还管你的 Activity 生命周期呢?最后我把重量级的数据存储放在了当数据发生变动(一些人为操作,或从服务器获取)的时候进行数据存储。

小结

Activity 的生命周期好像我们平时没怎么注意,因为觉得一切好像理所当然,但成功在于每一个细节,运用得当 Activity 的生命周期,让你的应用更加畅行无阻。

咦,一转眼都快到凌晨了,最近笔者的工作也是忙的飞起。但还是要马不停蹄地装逼,你看,「stormzhang」靠装逼帮公司融资 XXX 万,说明装逼就是有效果的。

Android 面试(二):如何理解 Activity 的生命周期_第4张图片
nanchen

做不完的开源,写不完的矫情。欢迎扫描下方二维码或者公众号搜索「nanchen」关注我的微信公众号,目前多运营 Android ,尽自己所能为你提升。如果你喜欢,为我点赞分享吧~


Android 面试(二):如何理解 Activity 的生命周期_第5张图片
nanchen

你可能感兴趣的:(Android 面试(二):如何理解 Activity 的生命周期)