您的位置:首页 > 移动开发 > Android开发

Android 应用程序的 Activity 启动过程及其生命周期

2014-06-22 00:32 375 查看
在Android系统中,Activity和Service是应用程序的核心组件,它们组合在一起构成了一个完整的应用程序,应用程序框架层提供了一套完整的机制来协助应用程序启动这些Activity和Service,以及提供Binder机制帮助它们相互间进行通信。
有两种操作会引发Activity的启动,一种用户点击应用程序图标时,Launcher会为我们启动应用程序的主Activity;应用程序的默认Activity启动起来后,它又可以在内部通过调用startActvity接口启动新的Activity,依此类推,每一个Activity都可以在内部启动新的Activity。通过这种连锁反应,按需启动Activity,从而完成应用程序的功能。
Activity的启动方式有两种,一种是显式的,一种是隐式的,隐式启动可以使得Activity之间的藕合性更加松散,因此,这里只关注隐式启动Activity的方法。
下面让我们首先通过一终流程图来看一下 Activity 的生命周期是怎样的,大家应该都很熟悉这张图吧



我来对这张流程做个简单的解释

1.启动Activity:系统会先调用onCreate方法,然后调用onStart方法,最后调用onResume,Activity进入运行状态。
2.当前Activity被其他Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行。
3.当前Activity由被覆盖状态回到前台或解锁屏:系统会调用onResume方法,再次进入运行状态。
4.当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:系统会先调用onPause方法,然后调用onStop方法,进入停滞状态。
5.用户后退回到此Activity:系统会先调用onRestart方法,然后调用onStart方法,最后调用onResume方法,再次进入运行状态。
6.当前Activity处于被覆盖状态或者后台不可见状态,即第2步和第4步,系统内存不足,杀死当前Activity,而后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。
7.用户退出当前Activity:系统先调用onPause方法,然后调用onStop方法,最后调用onDestory方法,结束当前Activity。

接着通过一个实例来看一下 Activity 的整个生命周期,闲话少说,都在代码里了...
src\cn\lion\activitytest
1. MainActivity.java
package cn.lion.activitytest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity{
private final static String LOG_TAG = "cn.lion.activitytest.MainActivity";
private Button startButton = null;
private int param = 1;

//Activity创建时被调用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

startButton = (Button)findViewById(R.id.button_start);
startButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Intent intent = new Intent("cn.lion.activitytest.subactivity");
startActivity(intent);
}
});

Log.i(LOG_TAG, "MainActivity onCreate() called");
}

//Activity创建或者从后台重新回到前台时被调用
@Override
protected void onStart(){
super.onStart();
Log.i(LOG_TAG, "MainActivity onStart() called");
}

//Activity从后台重新回到前台时被调用
@Override
protected void onRestart(){
super.onRestart();
Log.i(LOG_TAG, "MainActivity onRestart() called");
}

//Activity创建或者从被覆盖、后台重新回到前台时被调用
@Override
protected void onResume(){
super.onResume();
Log.i(LOG_TAG, "MainActivity onResume() called");
}

//Activity被覆盖到下面或者锁屏时被调用
@Override
protected void onPause() {
super.onPause();
Log.i(LOG_TAG, "MainActivity onPause() called");
//有可能在执行完onPause或onStop后,系统资源紧张将Activity杀死,所以有必要在此保存持久数据
}

//退出当前Activity或者跳转到新Activity时被调用
@Override
protected void onStop() {
super.onStop();
Log.i(LOG_TAG, "MainActivity onStop() called");
}

//退出当前Activity时被调用,调用之后Activity就结束了
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(LOG_TAG, "MainActivity onDestory() called");
}

//Activity窗口获得或失去焦点时被调用,在onResume之后或onPause之后
@Override
public void onWindowFocusChanged(boolean hasFocus){
super.onWindowFocusChanged(hasFocus);
Log.i(LOG_TAG, "MainActivity onWindowFocusChanged() called");
}

/**
* Activity被系统杀死时被调用.
* 例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死.
* 另外,当跳转到其他Activity或者按Home键回到主屏时该方法也会被调用,系统是为了保存当前View组件的状态.
* 在onPause之前被调用.
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt("param", param);
Log.i(LOG_TAG, " MainActivity onSaveInstanceState() called. put param: " + param);
super.onSaveInstanceState(outState);
}

/**
* Activity被系统杀死后再重建时被调用.
* 例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死,用户又启动该Activity.
* 这两种情况下onRestoreInstanceState都会被调用,在onStart之后.
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
param = savedInstanceState.getInt("param");
Log.i(LOG_TAG, "MainActivity onRestoreInstanceState() called. get param: " + param);
super.onRestoreInstanceState(savedInstanceState);
}
}

2. SubActivity.java
package cn.lion.activitytest;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class SubActivity extends Activity{
private final static String LOG_TAG = "cn.lion.activitytest.SubActivity";
private Button finishButton = null;
private int param = 2;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sub);

finishButton = (Button)findViewById(R.id.button_finish);
finishButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});

Log.i(LOG_TAG, "Sub Activity onCreate() called");
}

//Activity创建或者从后台重新回到前台时被调用
@Override
protected void onStart(){
super.onStart();
Log.i(LOG_TAG, "SubActivity onStart() called");
}

//Activity从后台重新回到前台时被调用
@Override
protected void onRestart(){
super.onRestart();
Log.i(LOG_TAG, "SubActivity onRestart() called");
}

//Activity创建或者从被覆盖、后台重新回到前台时被调用
@Override
protected void onResume(){
super.onResume();
Log.i(LOG_TAG, "SubActivity onResume() called");
}

//Activity被覆盖到下面或者锁屏时被调用
@Override
protected void onPause() {
super.onPause();
Log.i(LOG_TAG, "SubActivity onPause() called");
//有可能在执行完onPause或onStop后,系统资源紧张将Activity杀死,所以有必要在此保存持久数据
}

//退出当前Activity或者跳转到新Activity时被调用
@Override
protected void onStop() {
super.onStop();
Log.i(LOG_TAG, "SubActivity onStop() called");
}

//退出当前Activity时被调用,调用之后Activity就结束了
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(LOG_TAG, "SubActivity onDestory() called");
}

//Activity窗口获得或失去焦点时被调用,在onResume之后或onPause之后
@Override
public void onWindowFocusChanged(boolean hasFocus){
super.onWindowFocusChanged(hasFocus);
Log.i(LOG_TAG, "SubActivity onWindowFocusChanged() called");
}

/**
* Activity被系统杀死时被调用.
* 例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死.
* 另外,当跳转到其他Activity或者按Home键回到主屏时该方法也会被调用,系统是为了保存当前View组件的状态.
* 在onPause之前被调用.
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt("param", param);
Log.i(LOG_TAG, " SubActivity onSaveInstanceState() called. put param: " + param);
super.onSaveInstanceState(outState);
}

/**
* Activity被系统杀死后再重建时被调用.
* 例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死,用户又启动该Activity.
* 这两种情况下onRestoreInstanceState都会被调用,在onStart之后.
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
param = savedInstanceState.getInt("param");
Log.i(LOG_TAG, "SubActivity onRestoreInstanceState() called. get param: " + param);
super.onRestoreInstanceState(savedInstanceState);
}

}

res\values
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">ActivityTest</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="sub_activity">SubActivity</string>
<string name="start">Start-subActivity</string>
<string name="finish">Finish-activity</string>
</resources>

res\layout
1. activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center">
<Button
android:id="@+id/button_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/start" >
</Button>
</LinearLayout>


2. sub.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center">
<Button
android:id="@+id/button_finish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/finish" >
</Button>
</LinearLayout>

接着一步一步来对这个简单的应用进行操作,然后看一下它的执行结果(注意下面的 Log 信息是经过过滤器过滤的,我定义了一个只显示 cn.lion.activitytest* 类型信息的过滤器...)

1. 程序启动后的显示界面



Log 打印的信息如下



2. 点击上图的 Start-subActivity 按钮后,界面跳转如下



Log 的追加打印的信息如下



3. 点击上图的 Finish-activity 按钮后,界面跳转如下



Log 追加打印的信息如下



无论是通过点击应用程序图标来启动Activity,还是通过Activity内部调用startActivity接口来启动新的Activity,都要借助于应用程序框架层的ActivityManagerService服务进程。Service也是由ActivityManagerService进程来启动的。在Android应用程序框架层中,ActivityManagerService是一个非常重要的接口,它不但负责启动Activity和Service,还负责管理Activity和Service。
Android应用程序框架层中的ActivityManagerService启动Activity的过程大致如下图所示:



下面简要介绍一下启动的过程:
Step 1. 无论是通过Launcher来启动Activity,还是通过Activity内部调用startActivity接口来启动新的Activity,都通过Binder进程间通信进入到ActivityManagerService进程中,并且调用ActivityManagerService.startActivity接口;
Step 2. ActivityManagerService调用ActivityStack.startActivityMayWait来做准备要启动的Activity的相关信息;
Step 3. ActivityStack通知ApplicationThread要进行Activity启动调度了,这里的ApplicationThread代表的是调用ActivityManagerService.startActivity接口的进程,对于通过点击应用程序图标的情景来说,这个进程就是Launcher了,而对于通过在Activity内部调用startActivity的情景来说,这个进程就是这个Activity所在的进程了;
Step 4. ApplicationThread不执行真正的启动操作,它通过调用ActivityManagerService.activityPaused接口进入到ActivityManagerService进程中,看看是否需要创建新的进程来启动Activity;
Step 5. 对于通过点击应用程序图标来启动Activity的情景来说,ActivityManagerService在这一步中,会调用startProcessLocked来创建一个新的进程,而对于通过在Activity内部调用startActivity来启动新的Activity来说,这一步是不需要执行的,因为新的Activity就在原来的Activity所在的进程中进行启动;
Step 6. ActivityManagerServic调用ApplicationThread.scheduleLaunchActivity接口,通知相应的进程执行启动Activity的操作;
Step 7. ApplicationThread把这个启动Activity的操作转发给ActivityThread,ActivityThread通过ClassLoader导入相应的Activity类,然后把它启动起来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐