在构建 Activity的时候,需要在 AndroidManifest.xml注册对应的Activity组件,否则其是无法被系统识别的,具体注册过程如下:
<activity android:name=".MainActivity" android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
其中android:launchMode="standard"表示MainActivity使用的是standard启动模式,除了standard之外,Android还有singleTop,singleTask和singleInstance几种启动模式,下面分别介绍。
-
standard启动模式
standard是系统默认的启动模式,即在注册Activity的时候不指定任何launchMode的时候就会以这种方式来启动Activity。在这种启动模式下,无论栈中是否已经存在该Activity的实例,系统每次都会在栈顶创建一个新的Activity实例。
为了验证这点,写一个实现Activity自跳转的demo。
其注册过程如下:
<activity android:name=".MainActivity" android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
其代码如下:
public class MainActivity extends Activity {
private static final String TAG = "Android_Test";
private TextView mText;
private Button mButton;
private Button mButtonFirst;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mText = (TextView) findViewById(R.id.main_text);
mText.setText(this.toString());
Log.i(TAG, "onCreate: " + this.toString());
mButton = (Button) findViewById(R.id.main_button);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MainActivity.class);
startActivity(intent);
}
});
mButtonFirst = (Button) findViewById(R.id.main_button_first);
mButtonFirst.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, FirstActivity.class);
startActivity(intent);
}
});
}
}
在每次点击mButton的时候都会再次打开 MainActivity,为了更直观地看到是否有新的实例产生,增加了打印。在 MainActivity界面上点击三次mButton,通过下面的打印信息,我们可以确定这是产生了4个MainActivity实例,其中第一个实例是在启动应用时产生,后面三个是在点击mButton时通过startActivity产生。
02-13 13:59:37.263 11580 11580 I Android_Test: onCreate: com.test.androidtest.MainActivity@f608583
02-13 13:59:50.392 11580 11580 I Android_Test: onCreate: com.test.androidtest.MainActivity@2b97a9a
02-13 13:59:51.549 11580 11580 I Android_Test: onCreate: com.test.androidtest.MainActivity@322f6dd
02-13 13:59:52.555 11580 11580 I Android_Test: onCreate: com.test.androidtest.MainActivity@847cff1
整个过的栈变化如下图:

-
singleTop启动模式
singleTop又称栈顶复用模式,即当准备启动Activity的时候会先检查相应栈的栈顶是否就是需要启动的Activity实例,如果是就直接复用,否则就新创建一个实例放入栈顶。
为了验证这点,把上述的MainActivity的启动模式改为singleTop,如下:
<activity android:name=".MainActivity" android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
同样在MainActivity启动后点击mButton三次,观察是否有新的MainActivity实例产生。通过下面的打印可以发现,只是在应用启动的时候创建了一个MainActivity实例,后面的三次点击mButton都没有创建新的实例,这是因为栈顶已经是MainActivity实例了,无须创建直接复用即可。
02-13 14:28:25.767 12215 12215 I Android_Test: onCreate: com.test.androidtest.MainActivity@f608583
现在考虑这样一种情况:如果栈里已经有MainActivity实例,但是并不是位于栈顶,这时会不会创建新的MainActivity实例呢?我们创建一个新的 FirstActivity,通过MainActivity->FirstActivity->MainActivity这个过程,观察下启动模式为singleTop的MainActivity在FirstActivity界面上启动时,是否会创建新的实例。
FirstActivity的注册及逻辑代码如下:
<activity android:name=".FirstActivity" android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
public class FirstActivity extends Activity {
private static final String TAG = "Android_Test";
private TextView mText;
private Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
mText = (TextView) findViewById(R.id.first_text);
mText.setText(this.toString());
Log.i(TAG, "onCreate: " + this);
mButton = (Button) findViewById(R.id.first_button);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
}
MainActivity->FirstActivity->MainActivity过程中的打印如下,从中可以发现在 FirstActivity中启动MainActivity时会创建新的实例,这是因为当时栈顶是FirstActivity而不是MainActivity。这时再在MainActivity点击mButton再无MainActivity实例产生,这个过程再次证明了singleTop的栈顶复用特点。
02-13 14:37:21.447 12633 12633 I Android_Test: onCreate: com.test.androidtest.MainActivity@f608583
02-13 14:37:23.320 12633 12633 I Android_Test: onCreate: com.test.androidtest.FirstActivity@2b0953
02-13 14:37:27.226 12633 12633 I Android_Test: onCreate: com.test.androidtest.MainActivity@78e4923
-
singleTask启动模式
singleTask又称栈内复用,即在准备创建新的Activity实例时会检查栈内是否有该Activity实例,如果有就会把栈内位于该实例之上的所有其他Activity实例全部出栈并复用该Activity实例,如果没有就创建一个新的实例放入栈。
为了验证这点,把MainActivity的启动模式改为singleTask,如下:
<activity android:name=".MainActivity" android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
考虑和singlgeTop同样的操作,即MainActivity->FirstActivity->MainActivity,从整个过程的打印可以发现,在FirstActivity界面启动MainActivity时并没有创建新的实例,而是直接复用位于栈顶的MainActivity实例并把FirstActivity出栈,这就证明了singleTask的栈内复用的特点。
02-13 14:55:50.140 12983 12983 I Android_Test: onCreate: com.test.androidtest.MainActivity@f608583
02-13 14:55:52.627 12983 12983 I Android_Test: onCreate: com.test.androidtest.FirstActivity@4d2e7af
-
singleInstance启动模式
singleInstance又称单例模式,在整个内存中会为该Activity创建唯一实例并使之位于单独的栈中,所有应用在使用该Activity的时候都是共享该实例。