安卓开发——活动的启动模式
实际项目中要为每个活动要指定恰当的启动模式。启动模式一共有四种:standard
、singleTop
、singleTask
、singleInstance
通过在A-M文件中给<activity>
标签指定android:launchMode
属性来选择启动模式。
一、standard
- 默认的启动模式
- 每启动一个新的活动,它就会从返回栈入栈并位于栈顶
- 系统不在乎这个栈是否已经在返回栈中存在,每次启动都会创建该活动的新实例
继续使用《Android开发——intent在活动间传递数据》这里的代码,修改FirstActivity
:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout); // 加载布局文件
Log.d(TAG, this.toString());
Button button1 = (Button) findViewById(R.id.button_1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this, FirstActivity.class);
startActivity(intent);
}
});
}
在FirstActivity
的基础上启动FirstActivity
,并点两次按钮:
发现要点三次BACK
才能返回桌面
二、singleTop
当启动活动时发现返回栈的栈顶已经是该活动,则直接使用,不再创建新的活动。
修改A-M文件:
<activity
android:launchMode="singleTop"
android:name=".FirstActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
这次连续点也只是只有一条信息打印出来,按一下BACK
就返回了
不过当FirstActivity
未处于栈顶时,启动FirstActivity
还是会创建新的实例,这次继续修改代码:FirstActivity
:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout); // 加载布局文件
Log.d(TAG, this.toString());
Button button1 = (Button) findViewById(R.id.button_1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
}
});
}
SecondActivity
:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_second);
Log.d(TAG, this.toString());
Button button2 = (Button)findViewById(R.id.button_2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(SecondActivity.this, FirstActivity.class);
startActivity(intent);
}
});
}
此时点一下按钮会到SecondActivity
,再点一下会又创建FirstActivity
返回要按下三次BACK
三、singleTask
每次启动活动时会现在返回栈检查是否存在该活动的实例,存在则直接使用,并把其他活动全部出栈;不存在则创建。
继续修改A-M:
<activity
android:launchMode="singleTask"
android:name=".FirstActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
然后在FirstAcivity
中添加onRestart()
方法,关于onRestart
可以参考这里
,并打印日志:
@Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "onRestart: 活动由停止态变为运行态");
}
在SecondActivity
中添加onDestroy()
方法:
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: 活动被销毁前调用");
}
运行:
点过去,点回来:
可以看到,系统返回FirstActivity
时将其他的栈销毁【出栈】,此时按一下BACK
即可退出程序。
四、singleInstance
每个应用都有自己的返回栈,而singleInstance
会启用一个新的返回栈来管理这个活动,这样可以使多个应用共用同一个返回栈,实现了共享活动实例。
继续修改A-M:
<activity
android:launchMode="singleInstance"
android:name=".SecondActivity">
<intent-filter>
<action android:name="com.example.day01_empty.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.example.day01_empty.my_category" />
</intent-filter>
</activity>
修改FirstActivity
:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout); // 加载布局文件
Log.d(TAG, "id是"+getTaskId());
Button button1 = (Button) findViewById(R.id.button_1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
}
});
}
修改SecondActivity
:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_second);
Log.d(TAG, "id是"+getTaskId());
Button button2 = (Button)findViewById(R.id.button_2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(SecondActivity.this, ThirdActivity.class);
startActivity(intent);
}
});
}
修改ThirdActivity
:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_third);
Log.d(TAG, "id是"+getTaskId());
}
然后运行并点两下按钮,可以看到SecondActivity
的TaskId
不同于其他两个活动:
说明SecondActivity
在单独的一个返回栈,接下来按一下BACK
:
结果从ThirdActivity
直接返回到FirstActivity
,再按一下Back
:
才返回到SecondActivity
。也就是说,只有一个返回栈空了,才会转到另外一个栈。
最后再BACK
一下就退出了。