一、Activity 启动模式
在实际项目中,应该根据项目的实际需要来为每个 Activity 指定恰当的启动模式 launchMode。启动模式一共有四种,分别是 standard、singleTop、singleTask 和 singleInstance。可以在 AndroidManifest.xml 中通过给 <activity> 标签指定 android:launchMode 属性来选择启动模式。
1、standard
standard 是 Activity 默认的启动模式,在不进行显示指定的情况下,所以 Activity 都会自动使用这种启动模式。Android 是使用返回栈来管理 Activity 的,在 standard 模式下,每当启动一个新的 Activity,它就会在返回栈中入栈,并处于栈顶的位置。对于使用 standard 模式的 Activity,系统不会在乎这个 Activity 是否已经在返回栈中存在,每次启动都会创建一个该 Activity 的新实例。
package com.android.common.activityimport android.content.Intent
import android.os.Bundle
import android.os.PersistableBundle
import android.util.Log
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import com.android.common.Rclass FirstActivity: AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {super.onCreate(savedInstanceState, persistentState)setContentView(R.layout.activity_main)Log.d("FirstActivity", this.toString())val button: Button = findViewById(R.id.button)button.setOnClickListener {val intent = Intent(this, FirstActivity::class.java)startActivity(intent)}}
}
上面为测试 standard 启动模式的代码,在 FirstActivity 界面上有一个 button 按钮,点击后再次打开 FirstActivity。每次点击按钮都会重新创建一个新的 FirstActivity 实例,点击3此,此时返回栈中也会存在 3 个 FirstActivity 实例,需要点击 3 次 Back 键才能退出程序。standard 模式原理示意图如下:
2、singleTop
当 Activity 的启动模式指定为 singleTop,在启动 Activity 时如果发现返回栈的栈顶已经是该 Activity,则认为可以直接使用它,不会再创建新的 Activity 实例。AndroidManifest.xml 中指定 Activity 的启动模式:
<activity android:name=".activity.FirstActivity"android:launchMode="singleTop" />
还是 standard 启动模式的例子,在 FirstActivity 中无论点击多少次,返回栈中始终只有一个 FirstActivity 的实例,只要按一次 Back 键就可以退出程序了。
不过当 FirstActivit 并未在栈顶位置时,再启动 FirstActivit 时还是会重新创建新的 FirstActivity 实例。例如,在 FirstActivity 中启动 SecondActivity,然后在 SecondActivity 中再启动 FirstActivity,由于此时栈顶已经不是 FirstActivity 了,所以此时启动 FirstActivity 时会重新创建新的实例,即使返回栈中已经存在 FirstActivity 的实例,该过程的原理示意图如下:
3、singleTask
使用 singleTask 模式可以很好地解决重复创建栈顶 Activity 的问题。当 Activity 的启动模式指定为 singleTask 时,每次启动该 Activity 时,系统首先会在返回栈中检查是否存在该 Activity 的实例,如果发现已经存在则直接使用该实例,并把在这个 Activity 之上的所有其他 Activity 统统出栈。如果没有发现就会创建一个新的 Activity 实例。
修改 AndroidManifest.xml 中 Activity 的启动模式:
<application>... <activity android:name=".activity.FirstActivity"android:launchMode="singleTask" />...</application>
假设有两个 Activity:FirstActivity 和 SecondActivity,在 FirstActivity 中点击按钮进入 SecondActivity,然后在 SecondActivity 中点击按钮启动 FirstActivity。在SendActivity中启动 FirstActivity 时,会发现返回栈中已经存在一个 FirstActivity,并且在 SecondActivity 下面,于是 SecondActivity 会从返回栈中出栈,而 FirstActivity 会重新成为栈顶的 Activity。现在返回栈中只剩下一个 FirstActivity 的实例了,按一下 Back 键就可以退出程序了。原理示意图如下:
4、singleInstance
如果一个 Activity 被多个程序共享时,采用之前的三种启动模式是做不到的,因为每个应用程序都会有自己的返回栈,同一个 Activity 在不同的返回栈中入栈时必然会创建新的实例。这种时候需要采用 singleInstance 启动模式,singleInstance 模式的 Activity 会启用一个新的返回栈来管理这个 Activity,不管是哪个应用程序来访问这个 Activity,都能共用同一个返回栈,也就解决了共享 Activity 实例的问题。
示例:在 FirstActivity 中点击按钮进入 SecondActivity 界面,然后在 SecondActivity 中点击按钮进入 ThirdActivity 界面,其中 SecondActivity 的启动方式指定为 singleInstance,原理示意图如下:
原理图上可以看出,指定为 singleInstance 启动模式的 SecondActivity 启动了一个新的返回栈。此时按下 Back 键进行返回,会发现 ThirdActivity 直接返回到了 FirstActivity,再按下 Back 键又会返回到 SecondActivity,再按下 Back 键才会退出程序。
二、应用场景
1、singleTop 的使用场景
- 广播消息。当在 ActivityA 界面时,此时收到一条广播信息,要求打开 ActivityA 界面,此时就没必要再次创建一个新的 ActivityA 实例放在栈顶,否则退出 ActivityA 界面时就需要按两次 Back 键才能退出。
- 微信的搜索功能。但点击搜索按钮后,微信就会跳到查询结果界面,在查询结果界面,为了能够继续查询,还是要显示搜索框,这种场景就需要用到 singleTop 启动模式,否则搜索几次就要按几次返回按钮才能回到主界面。
2、singleTask 的使用场景
该启动模式主要运用在主界面,无论后面打开了多少界面,只要再次回调主界面,返回栈中就应该只有一个主界面处于栈顶,否则退出程序时需要按多次退出按钮。
3、singleInstance 的使用场景
该模式主要用于 Activity 被多个应用程序共享时,无论哪个应用程序来访问这个 Activity,都共用同一个返回栈。
参考
《第一行代码 ——Android(第3版)》