Activity的暂停过程

resumeTopActivityInnerLocked

暂停过程的代码在 ActivityStack.resumeTopActivityInnerLocked

该函数主要功能

  • 当找不到需要resume的Activity,则直接回到桌面
  • 否则,当mResumedActivity不为空,则执行 startPausingLocked() 暂停该activity
  • 处理结束调用startSpecificActivityLocked函数

暂停过程

在启动一个Activity之前,需要先暂停正在运行的Activity,暂停过程是非常轻量级的

判断Activity对象是否存在

判断是否为用户离开产生的暂停消息

Android后台会自动检测用户多长时间没有和当前Activity交互了,如果程序允许该Activity接收用户离开消息,那么系统判断是用户离开,就会暂停目标Activity.此时 hadlePauseActivity的参数 userLeave为true,开发人员可以重载Activity的 onUserLeaving 进行监听

startPausingLocked()完成暂停

  1. 通过Binder发送消息给ApplicationThread 的 schedulePauseActivity 函数来暂停
  2. 进入应用程序进程的 performPauseActivity 进行暂停操作
  3. 检查是否已经pause,否则抛出异常,一般不会
  4. 回调 onSaveInstanceState 和 onPause
  5. 通过Binder 调用 activityPaused(token) 函数通知AMS已经暂停完毕

总结

暂停过程中开销最多的就是 onSaveInstanceState,而这段代码不一定会被执行,只有当saveState为true的时候才执行,而Activity内部的所有变量都还保存在内存当中,下一个要执行的Activity如果不是全屏的话,用户还可以看到刚才暂停的页面

唯一区别是被暂停的Activity将不能接收到用户消息,因为WMS在接收到用户消息后,仅仅把消息 dispatch 给当前窗口

由于被暂停的Activity的内部数据都被保留,包括内部的Handler对象,其所在的进程也依然保存,因此如果当前的Activity向已经pause的Activity的Handler发送一个消息,处于暂停状态的Activity中的Handle的handleMessage会被执行

重点
被暂停的Activity只是被WMS剥夺了接收消息的权利,如果改变WMS内部的消息分发机制,允许根据用户点击的位置发送到对应的Activity的话,那么这些Activity都会处于活动状态,这就是多窗口多任务

参考书籍: Android内核剖析