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
2. SubActivity.java
res\values
strings.xml
res\layout
1. activity_main.xml
2. sub.xml
接着一步一步来对这个简单的应用进行操作,然后看一下它的执行结果(注意下面的 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类,然后把它启动起来。
有两种操作会引发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类,然后把它启动起来。
相关文章推荐
- Android应用程序内部启动Activity过程(startActivity)的源代码分析
- Android应用程序的Activity启动过程简要介绍和学习计划 .
- Android应用程序在新的进程中启动新的Activity的方法和过程分析
- Android应用程序内部启动Activity过程(startActivity)的源代码分析
- Android应用程序在新的进程中启动新的Activity的方法和过程分析
- Android应用程序的Activity启动过程简要介绍和学习计划
- Android应用程序内部启动Activity过程(startActivity)的源代码分析
- Android应用程序在新的进程中启动新的Activity的方法和过程分析
- Android应用程序内部启动Activity过程(startActivity)的源代码分析
- Android启动过程 && Activity的生命周期 && Activity的开机自启动
- Android应用程序的Activity启动过程简要介绍和学习计划
- Android应用程序内部启动Activity过程(startActivity)的源代码分析
- Android应用程序的Activity启动过程简要介绍
- 转 Android应用程序在新的进程中启动新的Activity的方法和过程分析 .
- Android应用程序在新的进程中启动新的Activity的方法和过程分析
- Android应用程序的Activity启动过程简要介绍和学习计划
- Android应用程序的Activity启动过程简要介绍和学习计划
- 老罗的Android之旅——Android应用程序的Activity启动过程简要介绍和学习计划
- Android启动过程 && Activity生命周期 && Activity开机自启动 && this与getBaseContext && Activity的singleTask类型
- Android应用程序在新的进程中启动新的Activity的方法和过程分析