Activity的启动模式
Posted z啵唧啵唧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Activity的启动模式相关的知识,希望对你有一定的参考价值。
文章目录
Activity的启动模式
- 在实际的项目当中,我们应该根据特定的需求给每个Avtivity指定恰当的启动模式
- 启动模式一共包含四种:standard,singleTop,singleTask,singleInstance
- 指定启动模式的方法:在androidManifest.xml中通过标签指定android:launchMode属性来选择相应的启动模式.
standard
- standard是Activity默认的启动模式
- 在standard启动模式下,每当启动一个新的Activity就会在返回栈当中入栈,并且处在栈顶的位置.
- 对于使用standard启动模式的Activity,系统不会在乎返回栈中是否存在这个Activity,每次启动都会创建一个该Activity的实例
- 体会一下standard启动模式
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
Log.d("FirstActivity", this.toString())
setContentView(R.layout.first_layout)
button1.setOnClickListener
val intent = Intent(this, FirstActivity::class.java)
startActivity(intent)
- 这段代码是在FirstActivity中调用FirstActivity,通过测试可以发现每次点击按钮都会创建一个新的Activity实例.
- standard模式原理运行图
singleTop
- 在有些时候,standard会显得不太合理,因为明明栈顶已经存在相应的实例了,我们应该直接复用即可,可是standard不管三七二十先创建新的实例.
- 针对这一点,singleTop做了优化,当返回栈的栈顶是我们需要创建的实例的时候,那么则认为可以直接使用它.不会再创建新的Activity实例.
- 在AndroidManifest.xml中修改Activity的启动模式
<activity
android:name=".FirstActivity"
android:exported="true"
android:label="This is FirstActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
- android:launchMode="singleTop"来指定Activity的启动模式
- 此时我们再点击按钮,无论点击多少次,都只会创建一个FirstActivity的实例,仅按一次返回键就可以退出程序
- 不过当FirstActivity并未处在栈顶的时候,再启动FirstActivity还是会创建新的实例.
- singleTop的原理模式图
singleTask
- 使用singleTop可以很好的解决重复创建栈顶的Activity的问题,但是当Activity并没有处在栈顶的时候就还是会存在重复创建Activity的情况.
- 那么此时singleTask就是用来保证某个Activity在程序的上下文中只存在一个实例.
- 当Activity的启动模式指定为singleTask的时候,每次启动Activity的时候,系统首先会在返回栈中检查是否存在该Activity的实例,如果存在,就将这个Activity之上的所有Activity进行出栈,如果没有发现存在该Activity的实例,那么就会创建一个该Activity的实例.
singleInstance
- singleInstance是四种启动模式当中最特殊也是最复杂的一个.
- 指定为singleInstance启动模式的Activity会启动一个新的返回栈来管理这个Activity
- 当我们的Activity是多个程序程序所共享的时候,就应该需要用到这种启动模式,因为其他三种的启动模式都是自己独有的返回栈来管理Activity,所以不能将一个Activity进行共享.
- 实践singleInstance
<!--在AndroidManifest.xml中修改SecondActivity的启动模式-->
<activity
android:name=".SecondActivity"
android:exported="false"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="com.zb.activitytest.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MY_CATEGORY" />
</intent-filter>
</activity>
- 修改FirstActivity中的代码
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
//在onCreate方法中打印返回栈的id
Log.d("FirstActivity", "This is $taskId")
setContentView(R.layout.first_layout)
//启动ThirdActivity
val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
- 修改SecondActivity中的代码
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
Log.d("SecondActivity", "Task id is $taskId")
setContentView(R.layout.second_layout)
button2.setOnClickListener
val intent = Intent(this, ThirdActivity::class.java)
startActivity(intent)
- 修改ThirdActivity中的代码
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
Log.d("ThirdActivity", "Task id is $taskId")
setContentView(R.layout.third_layout)
- 运行代码,依次点击按钮,通过打印的日志发现FirstActivity和ThirdActivity的task id是一样的,但是SecondActivity的task id是不同于其他两个
- 这个说明SecondActivity确实是存在于一个单独的返回栈当中的,而且在这个栈当中只存在SecondActivity这一个Activity
- singleInstance模式原理如图:
以上是关于Activity的启动模式的主要内容,如果未能解决你的问题,请参考以下文章