Android组件学习-Activity

Activity的生命周期

Activity的生命周期应该是入门级知识了. 正常情况下, 一个Activity会经历create、start、resume、run、pause、stop、destory七个阶段. 当然, 有时Activity还会经历restart这个阶段. 在介绍各个阶段之前, 我先放一张各个状态之间的跳转图:

create阶段

Activity被创建于create阶段. 所以我们一般在onCreate函数里写加载界面布局的setContentView方法以及初始化各种控件.

start阶段

在start阶段, Activity已经被创建完, 但是因为还没有出现在前台, 所以我们还看不到. 大家在打开一款app时, 可能会看到app在刚打开的一瞬间是空白的, 那实际上就是Activity的start阶段. 因为restart阶段也可以跳转到start阶段, 所以其实我一般是喜欢把控件的数据加载放到onStart里写的.

resume阶段

resume阶段和start阶段不同地方就在于这时候Activity已经来到了前台. 可以说, resume是一个时间点. 在这个时间点前, Activity还不能与用户交互; 在这个时间点后, Activity就开始正常运行了. 因为这个阶段已经对用户可见了, 所以一般会在onResume方法里写一些和界面有关的东西. 比如希望用户在打开这个Activity的时候能够直接看到某一个部分, 那么可以把scrollTo函数写在这里.

run阶段

run阶段就是正常的运行阶段了, 没有什么好说的.

pause阶段

pause阶段是给Activity留的一个缓冲阶段, 因为一般在执行完onPause方法后, Activity就会立刻执行onStop方法. 一般来说, 在Activity被销毁后移入后台前, 我都会在这个阶段做一些数据的存储和内存的回收工作.

当然, 也有特殊情况. 比如说当我们在一个Activity上弹出一个Dialog或者PopupWindow的时候, 因为Activity还是可见的, 所以我们应该能推测出这时候它还没有到后台. 也就是说, 在这种情况下, Activity只执行了onPause方法. 当Dialog或者PopupWindow关闭后, Activity就从Resume状态开始.

stop阶段

stop阶段也可以理解为一个时间点. 在这个时间点之后, Activity要么被销毁, 要么移到后台. 理论上, 在这个阶段应该也可以做一些内存的回收工作. Activity在调用完onStop方法后, 就会被移入后台. 在这之后, Activity要么重新回到前台, 要么被进程销毁, 要么随着进程被系统杀死而被一起销毁.

destory阶段

destory阶段是Activity在被销毁前进入的最后一个阶段. 之所以设计这个阶段, 我觉得更多的还是想为开发者提供一个彻底清理内存的时间. 因为在pause或者stop阶段, 我们不知道Activity最终是否会被销毁, 如果在这时做一些重量级的内存清理工作, 要是activity又重新回到前台, 就还要重新再申请内存. 在destory阶段, 这个Activity基本上不会会有起死回生的可能了. 因此我们要在这个阶段把没有清掉的内存清理掉, 避免造成内存泄漏.

restart阶段

当移入后台的Activity重新回到前台时, Activity就会调用onRestart方法. 因为我基本上把加载数据都放在了resume阶段, 所以restart阶段我也没有怎么用过. 也许一些功能在实现时会使用到这个阶段.

Activity的启动模式

starndard模式

我们都知道, Android是用栈来管理一个app内Activity之间的跳转关系的. 比如说我们打开了一个app, MainActivity就会进入到这个app的任务栈中. 当我们从MainActivity跳转到ActivityA后, Activity就会进入任务栈. 当我们在ActivityA上按返回键时, ActivityA就会出栈, 这样我们就回到了MainActivity里. 我们可以再看一下示意图:

我们常用的这种启动模式叫做standard模式. 一般来说, standard模式是Android默认的启动模式. 我们很容易想到, 如果页面不断的跳转, 那么栈内的Activity就会越来越多, 这样很容易爆掉. 要解决这个问题, 我们就需要不一样的启动模式.

singleTop模式

这个模式看名字就知道是什么意思了. 当一个Activity在栈顶的时候, 如果我们需要再跳转到这种Activity并且这种Activity的启动模式是singleTop, 那么系统不会再创建一个新的Activity, 而是通过让这个Activity调用onNewIntent来复用这个Activity. 我们可以看一下示意图:

就像上图一样, 我们在ActivityA中再跳转至ActivityA, 系统会直接复用这个ActivityA而不是再生成一个ActivityA. 当然, 因为是复用, 所以实际上只有一个ActivityA. 如果我们再按下返回键, 应用会直接回到MainActivity而不是上一个ActivityA.

singleTask模式

理解了singleTop模式, singleTask模式就很好理解了. singleTop模式复用Activity的前提是Activity在栈顶, 而singleTask只要求Activity在栈内. 当然这么做也有一定的损失. 因为复用Activity就要把栈内的这个被复用的Activity移到栈顶, 这就意味着这个Activity上面的那些Activity都要出栈. 我们可以看一下示意图:

如上图所示, 当我们要从ActivityB跳转到ActivityA时, 因为是栈内复用, ActivityB就要出栈. 这时如果我们再按下返回键, 应用就会回到MainActivity中.

singleInstance模式

个启动模式比较特殊. 使用singleInstance模式的Activity会被单独分配到一个栈, 而且系统保证这个栈不会再有别的Activity进入. 这个模式的示意图不是很好画, 但是我在网上找到了一个比较形象的图:

这张图描述了两种情况.

第一种情况: 我从FirstActivity跳转到singleInstance的SecondActivity, 系统会给SecondActivity单独分配一个任务栈. 当我们在SecondActivity上按下返回键时, 我们就回到FirstActivity的栈里. 当我们再按下返回键时, FirstActivity栈空, 我们就退出了程序.

第二种情况: 如果我没有在SecondActivity上按下返回键, 而是跳转到新的FirstActivity里, 我们还是会回到FirstActivity的任务栈中, 但是这次当FirstActivity栈空时, 我们不会退出程序, 而是回到了SecondActivity的栈. 这个逻辑说合理也合理, 说不合理也不合理, 大家知道就行. 反正我到现在也还没有想出一个需要用到这个模式的情景……