深入理解Android Activity生命周期
activity
是一个提供用户交互的窗口,activity
之内可以包含多个view
去实现具体的显示和交互。activity
一般是以全屏的形式出现,也有特殊情况比如内嵌在另一个activity
中。
Google给出了activity
的生命周期流程图如下
生命周期函数
activity
生命周期函数是由android
操作系统调用,我们如上可以复写某个(或多个)函数,实现更多的功能。比如管理音乐软件的后台播放功能。
函数 | 调用时机 |
---|---|
OnCreate | 在activity对象被第一次创建时候调用 |
OnStart | 在activity变得可见时调用 |
OnResume | 在activity开始准备与用户交互时调用(不释放内存) |
OnPause | 在系统即将启动另外一个activity之前调用(不释放内存) |
OnStop | 当前activity变得不可见时调用 |
OnRestart | 当一个activity再次被启动之前调用 |
OnDestroy | 当前activity被销毁之前调用 |
多个activity
的实现方法
定义多个activity
- 首先定义一个类,继承
activity
- 在该类当中,复写
activity
当中的OnCreate
方法 - 在
AndroidManifest.xml
文件中注册该activity
启动一个activity
的方法
- 生成一个意图对象
Intent
- 调用
setClass
方法设置所要启动的activity
,其中第一个参数是packageContext
,就是当前类中应用的包名;第二个参数是意图要设置的类的名称。 - 调用
startActivity
方法启动activity
在这里复写了MainActivity
中的七种方法,为了更清晰的了解activity
的生命周期,这里还创建第二个activity
,以便观察不同时期activity
的状态。本例中调用SystemOut
输出activity
的状态。设置监听器ButtonListener
,在点击按钮的时候启动第二个activity
。
1 | public class MainActivity extends AppCompatActivity { |
第二个activity
,命名为SecondActivity
,同样复写其中的七个生命周期函数
1 | package com.cheryl.multiactivity; |
AndroidManifest.xml
文件中注册第二个activity
,在<application>
标签结束之前添加如下代码:
1 | <activity android:name=".SecondActivity" android:label="SecondActivity"> |
Back Stack
安卓应用中通常包含多个activity
,每个activity
都是围绕不同的内容设计,而且可以打开别的activity
,甚至是其他app中的activity
,比如分享或者在浏览器中打开等等功能。在一个特定的功能当中,一个任务(task)就等于是多个activity
的集合。
一般情况下,安卓系统中会同时运行多个apps,系统就需要同时管理多个apps,且每个任务中有很多任务。当用户启动一个应用程序的时候,当前app就会在前台显示。另一个app被开启的时候,新的app就会在旧app的顶端显示,同时获得焦点。旧的app被压入back stack栈中。当用户点击返回按钮,位于栈顶的activity
被弹出,底部的activity
会在前台显示并获得焦点。back stack栈中activity
的顺序不能被改变,只能压入栈push,或者弹出栈pop。如果用户持续点击返回,栈内的activity
会依次弹出,前台显示之前的activity
,直到显示主页,back stack栈为空。
当用户开启新的任务,或者回到主页,一个任务在后台的状态下仍会保持以一个整体的形式存放。当任务被存放在后台,所有的activity
都是stopped状态,但仍会保持完整性,只是暂时失去焦点,焦点被另一个activity
所取代。举例用户在使用app A,且app A包括三个activity
,在当前activity
之下还有两个存放在栈中。然后用户点击home按钮返回主页,然后开启一个新的app B,这时app A进入后台。系统会给app B开启新的任务和back stack,用户在完成app B中的工作后,按home键返回主页,再次进入app A,这时app A中保存的所有activity
会在暂停的位置获得焦点继续运行。如果用户返回app B,也会继续运行之前app B中的activity
。
因为activity
在back stack栈中的位置不能被改变,可能会导致某个activity
反复进出back stack栈(比如home activity
)。如果要改变这种行为,需要深入了解Navigation Design。
实例说明
在第一个activity
布局中设置一个按钮,让用户通过点击按钮进入第二个activity
。logcat
查看函数运行情况。
1 | <Button |
第二个activity
只显示文字
1 | <TextView |
- 运行App
输出如下,系统相继调用了OnCreate
,OnStart
和OnResume
方法。
1
2
3
01-07 12:39:15.775 I/System.out: MainActivity OnCreate
01-07 12:39:15.775 I/System.out: MainActivity OnStart
01-07 12:39:15.775 I/System.out: MainActivity OnResume
- 屏幕变暗休眠
系统调用OnPause
和OnStop
方法
1
2
01-07 12:39:45.840 I/System.out: MainActivity OnPause
01-07 12:39:45.860 I/System.out: MainActivity OnStop
- 再次点亮屏幕
1
2
3
01-07 12:44:55.085 I/System.out: MainActivity OnRestart
01-07 12:44:55.085 I/System.out: MainActivity OnStart
01-07 12:44:55.095 I/System.out: MainActivity OnResume
- 点击按钮进入第二个
activity
,可以看到系统是先暂停第一个activity
,创建和开始第二个activity
,第二个activity
准备与用户交互,最后再停掉第一个activity
。
1
2
3
4
5
01-07 12:47:10.355 I/System.out: MainActivity OnPause
01-07 12:47:10.410 I/System.out: SecondActivity OnCreate
01-07 12:47:10.410 I/System.out: SecondActivity OnStart
01-07 12:47:10.410 I/System.out: SecondActivity OnResume
01-07 12:47:10.575 I/System.out: MainActivity OnStop
- Home键
1
2
01-07 12:49:08.245 I/System.out: SecondActivity OnPause
01-07 12:49:08.560 I/System.out: SecondActivity OnStop
- 再次进入app
1
2
3
01-07 12:49:35.690 I/System.out: SecondActivity OnRestart
01-07 12:49:35.690 I/System.out: SecondActivity OnStart
01-07 12:49:35.690 I/System.out: SecondActivity OnResume
- Back键,app返回到第一个
activity
的页面。系统是先暂停第二个activity
,重新返回第一个activity
,然后销毁第二个activity
1
2
3
4
5
6
01-07 12:50:36.185 I/System.out: SecondActivity OnPause
01-07 12:50:36.200 I/System.out: MainActivity OnRestart
01-07 12:50:36.200 I/System.out: MainActivity OnStart
01-07 12:50:36.200 I/System.out: MainActivity OnResume
01-07 12:50:36.370 I/System.out: SecondActivity OnStop
01-07 12:50:36.370 I/System.out: SecondActivity OnDestroy
- 再次Back,回到系统主页,销毁第一个
activity
1
2
3
01-07 12:53:19.980 I/System.out: MainActivity OnPause
01-07 12:53:20.180 I/System.out: MainActivity OnStop
01-07 12:53:20.180 I/System.out: MainActivity OnDestroy
Intent对象基础
在第一段代码的Lisener函数里我们看到了intent
的使用,intent是即将要进行操作的一个抽象描述,可以用于启动另一个activity
,广播一个特定的组件信息,或者和后台服务通信。可以通俗的理解intent
,就是action
和data
的集合体。
An Intent is an object that provides runtime binding between separate components (such as two activities). The Intent represents an app’s “intent to do something.” You can use intents for a wide variety of tasks, but most often they’re used to start another activity.
简单理解就是,想要应用中做事件X,就把这个动作
和数据
写进intent
,在合适的时机使用或接收。主要有三个场景下比较常用:
- 在
activity
之间通过intent
对象传递数据 - 使用
putExtra()
系列方法向intent
对象中存储数据 - 使用
getXXXExtra()
系列方法从intent
对象中取出数据
通过以上方法,就可以实现不同activity
之间的通信
Reference
[1] https://developer.android.com/guide/components/activities/tasks-and-back-stack.html Google guide: Tasks and Back Stack
[2] http://blog.csdn.net/android_tutor/article/details/5772285 两分钟彻底让你明白Android Activity生命周期(图文)
[3] http://stackoverflow.com/questions/6578051/what-is-an-intent-in-android What is an Intent in Android?
[4] https://developer.android.com/reference/android/content/Intent.html Intent|Android Developers