在构建 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
整个过的栈变化如下图:
standard 启动模式
-
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
的时候都是共享该实例。
网友评论