以下是主要的测试代码
package com.hi.hello; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; public class SecondActivity extends Activity { private String TAG = "tag"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); Log.d(TAG, "--------SecondActivity---onCreate-----------"); findViewById(R.id.bt_click).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub startActivity(new Intent(SecondActivity.this, MainActivity.class)); } }); findViewById(R.id.bt_click_two).setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub startActivity(new Intent(SecondActivity.this, SecondActivity.class)); } }); } @Override protected void onNewIntent(Intent intent) { // TODO Auto-generated method stub super.onNewIntent(intent); Log.d(TAG, "--------SecondActivity---onNewIntent-----------"); } @Override protected void onRestart() { // TODO Auto-generated method stub super.onRestart(); Log.d(TAG, "-------SecondActivity----onRestart-----------"); } @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); Log.d(TAG, "--------SecondActivity---onStart-----------"); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); // 打印task id 和hashCode Log.d(TAG, "--------SecondActivity---onResume-----------task id:" + getTaskId() + "-----hashcode:" + hashCode()); } @Override protected void onPause() { // TODO Auto-generated method stub Log.d(TAG, "--------SecondActivity---onPause-----------"); super.onPause(); } @Override protected void onStop() { // TODO Auto-generated method stub super.onStop(); Log.d(TAG, "--------SecondActivity---onStop-----------"); } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.d(TAG, "-------SecondActivity----onDestroy-----------"); } }
Activity的启动模式在AndroidManifest,xml中中使用android:launchMode="xxxx"来配置的,
其中xxxx代表四种模式:standard,singleTop、singleTask,singleInstance模式。
在默认情况下,如果不使用launchMode来配置模式,那么Activity默认是standard模式。
一:standard
标准模式,也是Activity默认启动模式。
该模式下,不论该Activity的实例是否存在,每次启动Activity都会重新创建一个新的实例。
下面是打印的日志(SecondActivity的启动模式是standard,在SecondActivity界面2次启动SecondActivity自己的打印日志如下)
D/tag ( 2906): --------SecondActivity---onStop-----------
D/tag ( 2906): --------SecondActivity---onCreate-----------
D/tag ( 2906): --------SecondActivity---onStart-----------
D/tag ( 2906): --------SecondActivity---onResume-----------task id:8-----hashcode:1095904712
D/tag ( 2906): --------SecondActivity---onPause-----------
D/tag ( 2906): --------SecondActivity---onStop-----------
D/tag ( 2906): --------SecondActivity---onCreate-----------
D/tag ( 2906): --------SecondActivity---onStart-----------
D/tag ( 2906): --------SecondActivity---onResume-----------task id:8-----hashcode:1095950136
说明:
从以上日志中可以看出SecondActivity的taskId没变,但hashcode却变了,也就是新创建2个Activity实例。
也就证明“standard模式下,不论该Activity的实例是否存在,每次启动Activity都会重新创建一个新的实例”
二:singleTop
栈顶复用模式
在该模式下的任务栈内,如果Activity的实例已经位于栈顶,那么Activity不会被重新创建,通过onNewIntent()重新打开Activity;如果Activity的实例不在栈顶,那么Activity会被重新创建。
当Activity为singleTop模式是分为以下情况
- 如果Activity实例不存在,就创建一个新的Activity实例
- 如果Activity实例存在,但在于栈顶,则不会新创建Activity,而是通过onNewIntent()启动存在的实例
- 如果Activity实例存在,但不在栈顶(在站内),则创建一个新的Activity实例。
下面是打印的日志(SecondActivity的启动模式是singleTop )
日志一
SecondActivity在栈顶时
D/tag ( 3133): --------SecondActivity---onPause-----------
D/tag ( 3133): --------SecondActivity---onNewIntent-----------
D/tag ( 3133): --------SecondActivity---onResume-----------task id:9-----hashcode:1095875904
日志二
SecondActivity存在且不在栈顶时或者不存在时
D/tag ( 3133): --------SecondActivity---onCreate-----------
D/tag ( 3133): --------SecondActivity---onStart-----------
D/tag ( 3133): --------SecondActivity---onResume-----------task id:9-----hashcode:1095977008
说明:
通过日志一和日志二发现,hashcode不同(也就是不同实例)。当SecondActivity不在栈顶时,会重新创建一个新的实例;当SecondActivity在栈顶时,只是通过onNewIntent()启动SecondActivity,不会新创建实例。
三:singleTask
站内复用模式。
在该模式下的任务栈内,如果Activity的不存在,就会启动一个Activity实例;如果Activity的实例存在,那么会通过onNewIntent()再次启动Activity,并把该实例顶部的其他Activity实例全部移除。
当Activity为singleTask模式时,分如下情况说明
- 如果Activity实例不存在,就新创建一个实例;
- 如果Activity实例存在,但在于栈顶,就通过onNewIntent()启动存在的实例;
- 如果Activity实例存在,但在于站内(不在栈顶),就通过onNewIntent()启动Activity实例,同时把在于Activity实例之上的其他Activity实例全部抛出。
总的来说 SingleTask模式的Activity在同一个task中只有一个实例。
下面是打印的日志(SecondActivity的启动模式是singleTask)
日志一
SecondActivity实例不存在时
D/tag ( 3267): --------SecondActivity---onCreate-----------
D/tag ( 3267): --------SecondActivity---onStart-----------
D/tag ( 3267): --------SecondActivity---onResume-----------task id:11-----hashcode:1095632336
日志二
SecondActivity存在且在栈顶时(此时和singleTop一样,通过onNewIntent()启动)
D/tag ( 3267): --------SecondActivity---onPause-----------
D/tag ( 3267): --------SecondActivity---onNewIntent-----------
D/tag ( 3267): --------SecondActivity---onResume-----------task id:11-----hashcode:1095632336
日志三
SecondActivity存在切在栈内时(此时也是通过onNewIntent()启动存在的实例,但会把该实例顶部的实例全部杀死,如日志中的MainActivity被杀死)
D/tag ( 3267): ---MainActivity-onPause-----------
D/tag ( 3267): --------SecondActivity---onNewIntent-----------
D/tag ( 3267): -------SecondActivity----onRestart-----------
D/tag ( 3267): --------SecondActivity---onStart-----------
D/tag ( 3267): --------SecondActivity---onResume-----------task id:11-----hashcode:1095632336
D/tag ( 3267): ---MainActivity-onStop-----------
D/tag ( 3267): ---MainActivity-onDestroy-----------
四:singleInstance
单实例模式(singleInstance)的Activity在整个系统里只有一个实例。
如果不存在启动时,系统会创建一个新的任务栈,并且这个任务栈只有一个Activity实例。
其他的特性和singleTask和singleTop类似,具体如下分析
下面是打印的日志(SecondActivity的启动模式是singleInstance)
日志一
SecondActivity不存在时,就会在新的task中新创建一个
D/tag ( 2025): ---MainActivity-onCreate-----------
D/tag ( 2025): ---MainActivity--onStart-----------
D/tag ( 2025): ---MainActivity--onResume-------------task id:7
D/tag ( 2025): ---MainActivity-onPause-----------
D/tag ( 2025): --------SecondActivity---onCreate-----------
D/tag ( 2025): --------SecondActivity---onStart-----------
D/tag ( 2025): --------SecondActivity---onResume-----------task id:8-----hashcode:1091614320
D/tag ( 2025): ---MainActivity-onStop-----------
日志二
SecondActivity存在时且在栈内时,是通过onNewIntent()启动存在的实例,但不会杀死其他Activity实例(因为不在同一个任务栈中)
.......
D/tag ( 2025): ---MainActivity--onResume-------------task id:7
D/tag ( 2025): ---MainActivity-onPause-----------
D/tag ( 2025): --------SecondActivity---onNewIntent-----------
D/tag ( 2025): -------SecondActivity----onRestart-----------
D/tag ( 2025): --------SecondActivity---onStart-----------
D/tag ( 2025): --------SecondActivity---onResume-----------task id:8-----hashcode:1091614320
D/tag ( 2025): ---MainActivity-onStop-----------
日志三
SecondActivity存在时且在栈顶时,是通过onNewIntent()启动存在的实例
D/tag ( 2025): --------SecondActivity---onPause-----------
D/tag ( 2025): --------SecondActivity---onNewIntent-----------
D/tag ( 2025): --------SecondActivity---onResume-----------task id:8-----hashcode:1091614320
本文参考于《彻底弄懂Activity四大启动模式》和《如何正确理解和使用 Activity的4种启动模式》