activity是一个提供用户交互的窗口,activity之内可以包含多个view去实现具体的显示和交互。activity一般是以全屏的形式出现,也有特殊情况比如内嵌在另一个activity中。
Google给出了activity的生命周期流程图如下
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class MainActivity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
ButtonListener listener = new ButtonListener();
button.setOnClickListener(listener);
System.out.println("MainActivity OnCreate");
}

class ButtonListener implements View.OnClickListener{
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, SecondActivity.class);
startActivity(intent);
}
}

@Override
protected void onStart() {
super.onStart();
System.out.println("MainActivity OnStart");
}
@Override
protected void onStop() {
super.onStop();
System.out.println("MainActivity OnStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
System.out.println("MainActivity OnDestroy");
}
@Override
protected void onResume() {
super.onResume();
System.out.println("MainActivity OnResume");
}
@Override
protected void onPause() {
super.onResume();
System.out.println("MainActivity OnPause");
}
@Override
protected void onRestart() {
super.onResume();
System.out.println("MainActivity OnRestart");
}

第二个activity,命名为SecondActivity,同样复写其中的七个生命周期函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.cheryl.multiactivity;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
System.out.println("SecondActivity OnCreate");
}
@Override
protected void onStart() {
super.onStart();
System.out.println("SecondActivity OnStart");
}
@Override
protected void onStop() {
super.onStop();
System.out.println("SecondActivity OnStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
System.out.println("SecondActivity OnDestroy");
}
@Override
protected void onResume() {
super.onResume();
System.out.println("SecondActivity OnResume");
}
@Override
protected void onPause() {
super.onResume();
System.out.println("SecondActivity OnPause");
}
@Override
protected void onRestart() {
super.onResume();
System.out.println("SecondActivity OnRestart");
}

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布局中设置一个按钮,让用户通过点击按钮进入第二个activitylogcat查看函数运行情况。

1
2
3
4
5
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Call SecondActivity"/>

第二个activity只显示文字

1
2
3
4
5
<TextView
android:id="@+id/secondTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SecondActivity"/>
  • 运行App
    运行界面
    输出如下,系统相继调用了OnCreate,OnStartOnResume方法。
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
  • 屏幕变暗休眠
    系统调用OnPauseOnStop方法
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,就是actiondata的集合体。

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