欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

安卓开发——活动的启动模式

程序员文章站 2022-06-27 11:51:40
...

实际项目中要为每个活动要指定恰当的启动模式。启动模式一共有四种:
standardsingleTopsingleTasksingleInstance
通过在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());
}

然后运行并点两下按钮,可以看到SecondActivityTaskId不同于其他两个活动:
安卓开发——活动的启动模式
说明SecondActivity在单独的一个返回栈,接下来按一下BACK:
安卓开发——活动的启动模式
结果从ThirdActivity直接返回到FirstActivity,再按一下Back:
安卓开发——活动的启动模式
才返回到SecondActivity。也就是说,只有一个返回栈空了,才会转到另外一个栈。
最后再BACK一下就退出了。