Android 运用程序的生命周期 浅谈
在多数情况下, 每个Android应用运行在自己的Linux进程中. 当一个应用的某段code需要运行的时候这个进程将会被创建, 直到不再需要该应用或系统要为其他的应用释放内存的时候才停止
一个非常重要且少有的特性是, 应用进程的存活时间不是由这个应用直接控制的. 而是由系统决定的, 系统会根据每个已知的正在运行的应用情况来定夺, 包括, 该应用对用户的重要性和系统全部可用内存.
对于开发人员来讲, 了解每个应用组件(尤其是, Activity, Service, 和IntentReceiver)对于应用进程存活时间的影响是非常重要的. 如果没有正确使用, 可能会导致应用进程在处理重要工作的时候被系统杀掉.
在对应用进程生命周期的理解中, 一个典型的错误就是当一个IntentReceiver 接收到Intent 之后, 会在自己的onReceiveIntent()方法中开起一个线程, 而后return这个方法. 一旦这个方法return, 系统会认为这个IntentReceiver 不在处于活跃状态, 也就认为他的宿主进程不再需要(除非还包有其他活跃的应用组件). 以至于当系统需要回收内存的时候会随时释kill掉这个进程, 中止其中的子线程. 解决这个问题的办法是在IntentReceiver中启动一个Service, 这样系统会知道在这个进程中还有活跃的任务需要完成.
为了决定在内存较低的时候杀掉哪个进程, Android会根据运行在这些进程内的组件及他们的状态把进程划分成一个"重要程度层次". 其重要的程度按以下规则排序:
1. 前端进程可以是一个持有运行在屏幕最前端并与用户交互的Activity的进程 (onResume方法被调用时),也可以是持有一个正在运行的IntentReceiver(也就是说他正在执行自己的onReceiveIntent方法)的进程. 在系统中, 只会有少数这样的进程, 并且除非内存已经低到不够这些进程运行, 否则系统不会主动杀掉这些进程. 这时, 设备通常已经达到了需要内存整理的状态, 所以杀掉这些进程是为了不让用户界面停止响应.
1. 可视进程是持有一个被用户可见, 但没有显示在最前端 (onPause方法被调用时) 的Activity的进程. 举例来说, 这种进程通常出现在一个前端Activity以一个对话框出现并保持前一个Activity可见时. 这种进程被系统认为是极其重要的, 并且通常不会被杀掉, 除非为了保持所有前端进程正常运行不得不杀掉这些可见进程.
1. 服务进程是持有一个Service的进程, 该Service是由startService()方法启动的, 尽管这些进程用户不能直接看到, 但是通常他们做的工作用户是十分关注的(例如, 在后台播放mp3或是在后台下载 上传文件), 所以, 除非为了保持所有的前端进程和可视进程正常运行外, 系统是不会杀掉服务进程的.
1. 后台进程是持有一个不再被用户可见的Activity(onStop()方法被调用时)的进程. 这些进程不会直接影响用户体验. 加入这些进程已经完整的,正确的完成了自己的生命周期(访问Activity查看更多细节), 系统会在为前三种进程释放内存时随时杀掉这些后台进程. 通常会有很多的后台进程在运行, 所以这些进程被存放在一个LRU列表中, 以保证在低内存的时候, 最近一个被用户看到的进程会被最后杀掉.
1. 空进程是没有持有任何活动应用组件的进程. 保留这种进程的唯一理由是为了提供一种缓存机制, 缩短他的应用下次运行时的启动时间. 就其本身而言, 系统杀掉这些进程的目的是为了在这些空进程和底层的核心缓存之间平衡整个系统的资源.
当需要给一个进程分类的时候, 系统会在该进程中处于活动状态的所有组件里掉选一个重要等级最高作为分类依据. 查看Activity, Service,和IntentReceiver的文档, 了解每个组件在进程整个生命周期中的贡献. 每一个classes的文档详细描述他们在各自应用的生命周期中所起得作用.