Android开发:activity生命周期基础入门
activity的生命周期,作为Android的入门必备知识要领,activity的生命周期的重要性不言而喻。任何数据、交互都是由activity来呈现。
点这里,这是官方文档对activity生命周期的描述。如果嫌英文看起来费劲儿,那么,下面的介绍或许对于快速的了解activity生命周期有所助益。
教程上对activity 的生命周期一般都相对死板、难记。这里,我会结合自己的经验,分 为什么 ,是什么 , 雷区三个方面进行描述。
为什么要了解activity 的生命周期?
这得从android应用开发的框架的宏观层面说起。android应用android的应用程序有四大组件:
activity:通常展现为一个可视化的用户界面,可以理解为UI展现的载体。一般能处理一些简单的应用逻辑,但为了不阻碍界面交互的及时性,并不适用于大量的运算。
service:负责后台运行,没有用户界面,跟activity相辅相成。
broadcast reciver:不执行任何任务,仅仅是接受并响应广播通知的一类组件。这是整个app framwork下,应用功能复用的基石。
content provider:android是基于linux内核的。android下每个app都拥有一个用户名,独立的执行自己的进程。content provider为不同进程间的数据访问提供的可能。比如在app中加入通讯录功能,都通过它来完成。
近几年移动市场发展很快,但主流手机的资源配置仍然与电脑相比仍然相去甚远。应用框架的特性也是着力与解决这种资源的紧缺。
经过上面的文字,大家已经知道,activity控制着界面的显示。作为与用户交互的门面,activity状态控制是容不得半点马虎的。android使用activity栈(stack)来控制activity。
当前运行的activity,也就是当前显示并运行在屏幕上的activity,处于栈顶的位置。
当调用intent进入一个新的activity时,原先的activity就被新的activity压到栈内。
有时候,手机开启了多个app,内存资源紧缺,android为了保证当前app运行的良好,采用了销毁暂时不用的activity的办法。在这里,那些被压入activity栈内的不可见的activity就有危险了,系统可能牺牲它们来换取当前运行app的良好表现。注意,有种特殊情况,当正在运行的新activity并非全屏的或者半透明的时候,下面的activity依然可见,这时候那个作为背景的activity虽然已经停止运行,被从栈顶挤压到栈里,但却是万万不能销毁的啦,否则,就违背了android保证当前app运行的原则啦!(其实在app开发中为了达到好的视觉效果,这种状态的activity是很常见的)。于是,为了管理的方便,将activity的状态划分为如下几种: 当前运行的activity,未运行但可见的activity(前面这种特殊情况),未运行且不可见的activity,当然还有就是已经挂掉或者还未生成的activity(被解析掉了或者还不存在的activity)。
这或许就是生命周期存在的缘由。针对不同的状态,执行不同的功能,以免乱套。
计算机界有句话,“计算机里,任何问题都可以通过分层的方法来解决。” activity生命周期的划分大概也是使用了这种思想。分而治之,不同生命状态对应着不同的功能。
于是就有了下面这幅经典的activity lifecycle state 图。
Activity生命周期是怎么样的?
结合上面的文字,仔细看图。
看起来错综复杂,其实理解了上面那段话,也就基本掌握了脉络。
常规的,activity的创建必须经历 onCreate() --> onStart() --> onResume() 的过程,才能真正展现在你我眼前。
对应的“死亡”过程为onPause() --> onStop() --> onDestory().
回忆一下,根据之前的分析,activity的主要状态为4种
1,当前运行的activity
2,未运行但可见的activity
3,未运行且不可见的activity
4,不存在的activity
对应的每种状态之间的跳转需要一个激发:
1 --> 2 onPause() ##### 2 --> 1 onResume()
2 --> 3 onStop() ##### 3 --> 2 onStart()
3 --> 4 onDestory() ##### 4 --> 3 onCreate()
对于最基础的一个activity完全切换到另一个activity,一般会连环调用onPause(),onStop(),即旧的activity由状态1变为状态3.
对于有透明效果的activity的切换,旧activity没有完全从屏幕中离开,此时只对旧activity调用了pnPause(),处于状态2,未进入状态3.
小心踩雷
1,activity中调用dialog,虽然dialog被放在最前面,但dialog并不是一个activity。原来的activity是不会onPause的。
2,横竖屏切换的时候,activity是会被销毁再重建的。这里可用onSaveInstanceState方法储存需要的状态数据,并利用onRestoreInstanceState回复状态(onRestoreInstanceState(Bundle)里传入的Bundle参数是由onSaveInstanceState封装好的)。关于onSaveInstanceState的调用的详细介绍,点这里
3,如果activity中内容够多,在切换时,可能产生延迟。如果同时原来的activity还有背景音乐的控制能时,在onPause , onStop,还是onDestory中暂停音乐就比较关键了。不同选择有不同的用户体验效果。一般的,在哪个方法中存储数据,就在对应的回复方法中恢复数据,是相对安全的(比如在onStop中存储数据,在onStart中恢复数据),当然有特例。
4,一般来说,在重写onResume()等方法的代码时:如果是初始化一个activity,将自己的代码写在super方法的后面,让系统完成基本资源的初始化后,再执行自己的初始化代码。如果是结束一个activity,则将自己的代码写在super方法的前面,以免系统提前结束相应功能,妨碍自己的代码执行。当然,也有特例(For example, the theme I wanted to apply to my PreferenceActivity wouldn't take effect unless I put it before the superclass's onCreate(). )