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

    在Android系统中,Activity和Service是应用程序的核心组件,它们组合在一块儿构成了一个完整的应用程序,应用程序框架层提供了一套完整的机制来协助应用程序启动这些Activity和Service,以及提供Binder机制帮助它们相互间进行通讯。java

    有两种操做会引起Activity的启动,一种用户点击应用程序图标时,Launcher会为咱们启动应用程序的主Activity;应用程序的默认Activity启动起来后,它又能够在内部经过调用startActvity接口启动新的Activity,依此类推,每个Activity均可以在内部启动新的Activity。经过这种连锁反应,按需启动Activity,从而完成应用程序的功能。android

    Activity的启动方式有两种,一种是显式的,一种是隐式的,隐式启动可使得Activity之间的藕合性更加松散,所以,这里只关注隐式启动Activity的方法。web

    下面让咱们首先经过一终流程图来看一下 Activity 的生命周期是怎样的,你们应该都很熟悉这张图吧app

 

 

我来对这张流程作个简单的解释框架

1.启动Activity:系统会先调用onCreate方法,而后调用onStart方法,最后调用onResume,Activity进入运行状态。ide

2.当前Activity被其余Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行。spa

3.当前Activity由被覆盖状态回到前台或解锁屏:系统会调用onResume方法,再次进入运行状态。code

4.当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:系统会先调用onPause方法,而后调用onStop方法,进入停滞状态。orm

5.用户后退回到此Activity:系统会先调用onRestart方法,而后调用onStart方法,最后调用onResume方法,再次进入运行状态。xml

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类,而后把它启动起来。

相关文章
相关标签/搜索