Activity四大启动模式
ctivity的四种启动模式:
standard、singleTop、singleTask、singleInstance
为了打印方便,定义一个基础Activity,在其onCreate方法和onNewIntent方法中打印出当前Activity的日志信息,主要包括所属的task,当前类的hashcode,以及taskAffinity的值。之后我们进行测试的Activity都直接继承该Activity
- package com.lyf.launchmodektdemo
- import android.content.Intent
import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.ActionBar
import androidx.appcompat.app.AppCompatActivity- open class BaseActivity : AppCompatActivity() {
lateinit var actionBar: ActionBar- override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)- actionBar = supportActionBar!!
actionBar?.setDisplayHomeAsUpEnabled(true)- printTaskInfo(this, "onCreate")
dumpTaskAffinity(this)
}- override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
printTaskInfo(this, "onNewIntent")
dumpTaskAffinity(this)
}- override fun onRestart() {
super.onRestart()
printTaskInfo(this, "onRestart")
}- override fun onStart() {
super.onStart()
printTaskInfo(this, "onStart")
}- override fun onResume() {
super.onResume()
printTaskInfo(this, "onResume")
}- override fun onPause() {
super.onPause()
printTaskInfo(this, "onPause")
}- override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
printTaskInfo(this, "onSaveInstanceState")
}- override fun onStop() {
super.onStop()
printTaskInfo(this, "onStop")
}- override fun onDestroy() {
super.onDestroy()
printTaskInfo(this, "onDestroy")
}- override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> onBackPressed()
}
return super.onOptionsItemSelected(item)
}
}
此处还需要另一个Kotlin文件
- package com.lyf.launchmodektdemo
- import android.content.Context
- import android.content.Intent
- import android.content.pm.PackageManager
- import android.util.Log
- import androidx.appcompat.app.AppCompatActivity
- fun printTaskInfo(activity: BaseActivity, methodName: String) {
- log("$methodName: ${activity.localClassName} taskId: ${activity.taskId} hashCode: ${activity.hashCode()}")
- }
- fun log(message: String, tag: String = "LaunchMode") {
- Log.i(tag, message)
- }
- fun dumpTaskAffinity(activity: BaseActivity) {
- val info = activity.packageManager.getActivityInfo(
- activity.componentName,
- PackageManager.GET_META_DATA
- )
- log("taskAffinity: ${info.taskAffinity}")
- }
- /**
- * @param T 目标 Activity
- */
- inline fun <reified T : AppCompatActivity> Context.toActivity() {
- startActivity(Intent(this, T::class.java))
- }
一、standard——标准模式(默认模式)
这个模式是默认的启动模式,即标准模式,在不指定启动模式的前提下,系统默认使用该模式启动Activity,每次启动一个Activity都会重新创建一个新的实例,不管这个实例存不存在,这种模式下,谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈。这个Activity它的onCreate(),onStart(),onResume()方法都会被调用。
配置形式:
- <activity
android:name=".StandardActivity"
android:launchMode="standard" />
使用案例:
StandardActivity
对于standard模式,android:launchMode可以不进行声明,因为默认就是standard。
StandardActivity 的代码如下,入口Activity中有一个按钮进入该Activity,这个Activity中又有一个按钮启动StandardActivity。
- package com.lyf.launchmodektdemo
- import android.os.Bundle
import kotlinx.android.synthetic.main.activity_standard.*- class StandardActivity : BaseActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_standard)- btn_self.setOnClickListener {
toActivity<StandardActivity>()
}
}
}
进入StandardActivity,然后再点击两次“启动自身”按钮。
输出的日志如下:
- 2020-04-29 16:07:32.235 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onCreate: MainActivity taskId: 40477 hashCode: 32430795
2020-04-29 16:07:32.236 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:07:32.259 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStart: MainActivity taskId: 40477 hashCode: 32430795
2020-04-29 16:07:32.262 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onResume: MainActivity taskId: 40477 hashCode: 32430795- 2020-04-29 16:07:34.490 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onPause: MainActivity taskId: 40477 hashCode: 32430795
2020-04-29 16:07:34.518 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onCreate: StandardActivity taskId: 40477 hashCode: 90465235
2020-04-29 16:07:34.518 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:07:34.527 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStart: StandardActivity taskId: 40477 hashCode: 90465235
2020-04-29 16:07:34.532 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onResume: StandardActivity taskId: 40477 hashCode: 90465235
2020-04-29 16:07:34.867 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: MainActivity taskId: 40477 hashCode: 32430795
2020-04-29 16:07:34.869 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStop: MainActivity taskId: 40477 hashCode: 32430795- 2020-04-29 16:07:35.423 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onPause: StandardActivity taskId: 40477 hashCode: 90465235
2020-04-29 16:07:35.448 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onCreate: StandardActivity taskId: 40477 hashCode: 139304006
2020-04-29 16:07:35.449 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:07:35.455 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStart: StandardActivity taskId: 40477 hashCode: 139304006
2020-04-29 16:07:35.458 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onResume: StandardActivity taskId: 40477 hashCode: 139304006
2020-04-29 16:07:35.780 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: StandardActivity taskId: 40477 hashCode: 90465235
2020-04-29 16:07:35.782 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStop: StandardActivity taskId: 40477 hashCode: 90465235- 2020-04-29 16:07:36.215 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onPause: StandardActivity taskId: 40477 hashCode: 139304006
2020-04-29 16:07:36.240 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onCreate: StandardActivity taskId: 40477 hashCode: 102119413
2020-04-29 16:07:36.241 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:07:36.246 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStart: StandardActivity taskId: 40477 hashCode: 102119413
2020-04-29 16:07:36.249 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onResume: StandardActivity taskId: 40477 hashCode: 102119413
2020-04-29 16:07:36.576 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: StandardActivity taskId: 40477 hashCode: 139304006
2020-04-29 16:07:36.578 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStop: StandardActivity taskId: 40477 hashCode: 139304006
可以看到日志输出了三次StandardActivity的和一次MainActivity的,从MainActivity进入StandardActivity一次,后来我们又按了两次按钮,总共三次StandardActivity的日志,并且所属的任务栈的id都是40477,这也验证了谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈这句话,因为启动StandardActivity的是MainActivity,而MainActivity的taskId是40477,因此启动的StandardActivity也应该属于id为40477的这个task,后续的两个StandardActivity是被StandardActivity这个对象启动的,因此也应该还是40477,所以taskId都是40477。并且每一个Activity的hashcode都是不一样的,说明他们是不同的实例,即“每次启动一个Activity都会重新创建一个新的实例”。
二、singleTop——Task栈顶单例模式(栈顶复用模式)
此模式下,如果新的activity已经位于栈顶,那么这个activity不会被重新创建,同时他的onNewIntent方法会被调用,此时这个activity的onCreate(),onStart()方法没有回调,onResume()方法会被回调,所以这个activity没有发生改变,还是同一个activity。通过此方法的参数我们可以获取当前请求的信息。如果栈顶不存在该activity的实例,则情况与standard模式相同。
配置形式:
- <activity
android:name=".SingleTopActivity"
android:launchMode="singleTop"
android:taskAffinity="com.lyf.test.singleTop" />
使用案例:
SingleTopActivity
- package com.lyf.launchmodektdemo
- import android.os.Bundle
import kotlinx.android.synthetic.main.activity_single_top.*- class SingleTopActivity : BaseActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_single_top)- btn_self.setOnClickListener {
toActivity<SingleTopActivity>()
}- btn_other.setOnClickListener {
toActivity<OtherTopActivity>()
// toActivity<MainActivity>()
}
}
}
OtherTopActivity
- package com.lyf.launchmodektdemo
- import android.os.Bundle
import kotlinx.android.synthetic.main.activity_other_top.*- class OtherTopActivity : BaseActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_other_top)- btn_top.setOnClickListener {
toActivity<SingleTopActivity>()
}
}
}
1、和standard启动方式一样,先启动SingleTopActivity,然后点击两次“启动自身”按钮
输出日志如下:
- 2020-04-29 16:10:38.177 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onCreate: MainActivity taskId: 40478 hashCode: 264932
2020-04-29 16:10:38.178 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:10:38.194 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStart: MainActivity taskId: 40478 hashCode: 264932
2020-04-29 16:10:38.197 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onResume: MainActivity taskId: 40478 hashCode: 264932- 2020-04-29 16:10:39.872 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onPause: MainActivity taskId: 40478 hashCode: 264932
2020-04-29 16:10:39.902 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onCreate: SingleTopActivity taskId: 40478 hashCode: 246478133
2020-04-29 16:10:39.903 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:10:39.916 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleTopActivity taskId: 40478 hashCode: 246478133
2020-04-29 16:10:39.920 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleTopActivity taskId: 40478 hashCode: 246478133
2020-04-29 16:10:40.261 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: MainActivity taskId: 40478 hashCode: 264932
2020-04-29 16:10:40.263 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStop: MainActivity taskId: 40478 hashCode: 264932- 2020-04-29 16:10:42.664 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onPause: SingleTopActivity taskId: 40478 hashCode: 246478133
2020-04-29 16:10:42.666 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onNewIntent: SingleTopActivity taskId: 40478 hashCode: 246478133
2020-04-29 16:10:42.667 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:10:42.669 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleTopActivity taskId: 40478 hashCode: 246478133- 2020-04-29 16:10:44.706 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onPause: SingleTopActivity taskId: 40478 hashCode: 246478133
2020-04-29 16:10:44.707 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onNewIntent: SingleTopActivity taskId: 40478 hashCode: 246478133
2020-04-29 16:10:44.709 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:10:44.712 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleTopActivity taskId: 40478 hashCode: 246478133
从日志可以看出,除了第一次进入SingleTopActivity这个Activity时,输出的是onCreate方法中的日志,后续的都是调用了onNewIntent方法,并没有回调onCreate、onStart方法,回调了onResume方法,并且三个日志的hashcode都是一样的,说明栈中只有一个实例。这是因为第一次进入的时候,栈中没有该实例,则创建,后续的两次发现栈顶有这个实例,则直接复用,并且调用onNewIntent方法。
那么假设栈中有该实例,但是该实例不在栈顶情况又如何呢?
我们先从MainActivity进入到SingleTopActivity,然后点击“启动另外一个activity”启动OtherTopActivity,再从OtherTopActivity调回SingleTopActivity,再从SingleTopActivity跳到SingleTopActivity。日志如下:
- 2020-04-29 16:12:26.281 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onCreate: MainActivity taskId: 40479 hashCode: 213102559
2020-04-29 16:12:26.282 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:12:26.295 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStart: MainActivity taskId: 40479 hashCode: 213102559
2020-04-29 16:12:26.298 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onResume: MainActivity taskId: 40479 hashCode: 213102559- 2020-04-29 16:12:28.257 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onPause: MainActivity taskId: 40479 hashCode: 213102559
2020-04-29 16:12:28.283 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onCreate: SingleTopActivity taskId: 40479 hashCode: 178327198
2020-04-29 16:12:28.284 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:12:28.292 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleTopActivity taskId: 40479 hashCode: 178327198
2020-04-29 16:12:28.296 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleTopActivity taskId: 40479 hashCode: 178327198
2020-04-29 16:12:28.627 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: MainActivity taskId: 40479 hashCode: 213102559
2020-04-29 16:12:28.628 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStop: MainActivity taskId: 40479 hashCode: 213102559- 2020-04-29 16:12:30.413 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onPause: SingleTopActivity taskId: 40479 hashCode: 178327198
2020-04-29 16:12:30.441 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onCreate: OtherTopActivity taskId: 40479 hashCode: 135729268
2020-04-29 16:12:30.441 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:12:30.447 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStart: OtherTopActivity taskId: 40479 hashCode: 135729268
2020-04-29 16:12:30.450 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onResume: OtherTopActivity taskId: 40479 hashCode: 135729268
2020-04-29 16:12:30.767 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: SingleTopActivity taskId: 40479 hashCode: 178327198
2020-04-29 16:12:30.769 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStop: SingleTopActivity taskId: 40479 hashCode: 178327198- 2020-04-29 16:12:31.873 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onPause: OtherTopActivity taskId: 40479 hashCode: 135729268
2020-04-29 16:12:31.900 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onCreate: SingleTopActivity taskId: 40479 hashCode: 148854986
2020-04-29 16:12:31.900 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:12:31.909 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleTopActivity taskId: 40479 hashCode: 148854986
2020-04-29 16:12:31.912 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleTopActivity taskId: 40479 hashCode: 148854986
2020-04-29 16:12:32.244 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: OtherTopActivity taskId: 40479 hashCode: 135729268
2020-04-29 16:12:32.246 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onStop: OtherTopActivity taskId: 40479 hashCode: 135729268- 2020-04-29 16:12:35.347 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onPause: SingleTopActivity taskId: 40479 hashCode: 148854986
2020-04-29 16:12:35.348 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onNewIntent: SingleTopActivity taskId: 40479 hashCode: 148854986
2020-04-29 16:12:35.349 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:12:35.351 11953-11953/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleTopActivity taskId: 40479 hashCode: 148854986
我们看到从MainActivity进入到SingleTopActivity时,新建了一个SingleTopActivity对象,并且task id与MainActivity是一样的,然后从SingleTopActivity跳到OtherActivity时,新建了一个OtherActivity,此时task中存在三个Activity,从栈底到栈顶依次是MainActivity,SingleTopActivity,OtherActivity,此时如果再跳到SingleTopActivity,即使栈中已经有SingleTopActivity实例了,但是依然会创建一个新的SingleTopActivity实例,这一点从上面的日志的hashCode可以看出,此时栈顶是SingleTopActivity,如果再跳到SingleTopActivity,就会复用栈顶的SingleTopActivity,即会调用SingleTopActivity的onNewIntent方法。这就是上述日志的全过程。
对以上内容进行总结
standard启动模式是默认的启动模式,每次启动一个Activity都会新建一个实例不管栈中是否已有该Activity的实例。
singleTop模式分3种情况
- 当前栈中已有该Activity的实例并且该实例位于栈顶时,不会新建实例,而是复用栈顶的实例,并且会将Intent对象传入,回调onNewIntent方法
- 当前栈中已有该Activity的实例但是该实例不在栈顶时,其行为和standard启动模式一样,依然会创建一个新的实例
- 当前栈中不存在该Activity的实例时,其行为同standard启动模式
standard和singleTop启动模式都是在原任务栈中新建Activity实例,不会启动新的Task,即使你指定了taskAffinity属性。
那么什么是taskAffinity属性呢,可以简单的理解为任务相关性。
- 这个参数标识了一个Activity所需任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名
- 我们可以单独指定每一个Activity的taskAffinity属性覆盖默认值
- 一个任务的affinity决定于这个任务的根activity(root activity)的taskAffinity
- 在概念上,具有相同的affinity的activity(即设置了相同taskAffinity属性的activity)属于同一个任务
- 为一个activity的taskAffinity设置一个空字符串,表明这个activity不属于任何task
很重要的一点taskAffinity属性不对standard和singleTop模式有任何影响,即时你指定了该属性为其他不同的值,这两种启动模式下不会创建新的task(如果不指定即默认值,即包名)
指定方式如下:
- <activity
- android:name=".SingleTopActivity"
- android:launchMode="singleTop"
- android:taskAffinity="com.lyf.test.singleTop" />
三、singleTask——Task栈内单例模式(栈内复用模式)
这个模式十分复杂,有各式各样的组合。在这个模式下,如果栈中存在这个Activity的实例就会复用这个Activity,不管它是否位于栈顶,复用时,会将它上面的Activity全部出栈,并且会回调该实例的onNewIntent方法。其实这个过程还存在一个任务栈的匹配,因为这个模式启动时,会在自己需要的任务栈中寻找实例,这个任务栈就是通过taskAffinity属性指定。如果这个任务栈不存在,则会创建这个任务栈。
配置形式:
- <activity
android:name=".SingleTaskActivity"
android:launchMode="singleTask" />
使用案例:
SingleTaskActivity
- package com.lyf.launchmodektdemo
- import android.os.Bundle
import kotlinx.android.synthetic.main.activity_single_task.*- class SingleTaskActivity : BaseActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_single_task)- btn_self.setOnClickListener {
toActivity<SingleTaskActivity>()
}- btn_other.setOnClickListener {
toActivity<OtherTask1Activity>()
// toActivity<MainActivity>()
}
}
}
OtherTaskActivity
- package com.lyf.launchmodektdemo
- import android.os.Bundle
import kotlinx.android.synthetic.main.activity_other_task.*- class OtherTaskActivity : BaseActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_other_task)- btn_task.setOnClickListener {
toActivity<SingleTaskActivity>()
}
}
}
现在我们先不指定任何taskAffinity属性,对它做类似singleTop的操作,即从入口MainActivity进入SingleTaskActivity,然后跳到OtherTaskActivity,再跳回到SingleTaskActivity,然后再启动一次SingleTaskActivity。看看整个过程的日志。
- 2020-04-29 16:25:02.985 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onCreate: MainActivity taskId: 40489 hashCode: 184844997
2020-04-29 16:25:02.986 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:25:03.004 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onStart: MainActivity taskId: 40489 hashCode: 184844997
2020-04-29 16:25:03.009 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onResume: MainActivity taskId: 40489 hashCode: 184844997- 2020-04-29 16:25:05.158 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onPause: MainActivity taskId: 40489 hashCode: 184844997
2020-04-29 16:25:05.188 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onCreate: SingleTaskActivity taskId: 40489 hashCode: 259974370
2020-04-29 16:25:05.188 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:25:05.200 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleTaskActivity taskId: 40489 hashCode: 259974370
2020-04-29 16:25:05.204 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleTaskActivity taskId: 40489 hashCode: 259974370
2020-04-29 16:25:05.550 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: MainActivity taskId: 40489 hashCode: 184844997
2020-04-29 16:25:05.551 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onStop: MainActivity taskId: 40489 hashCode: 184844997- 2020-04-29 16:25:06.739 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onPause: SingleTaskActivity taskId: 40489 hashCode: 259974370
2020-04-29 16:25:06.770 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onCreate: OtherTaskActivity taskId: 40489 hashCode: 191707012
2020-04-29 16:25:06.771 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:25:06.777 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onStart: OtherTaskActivity taskId: 40489 hashCode: 191707012
2020-04-29 16:25:06.781 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onResume: OtherTaskActivity taskId: 40489 hashCode: 191707012
2020-04-29 16:25:07.108 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: SingleTaskActivity taskId: 40489 hashCode: 259974370
2020-04-29 16:25:07.110 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onStop: SingleTaskActivity taskId: 40489 hashCode: 259974370- 2020-04-29 16:25:08.044 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onPause: OtherTaskActivity taskId: 40489 hashCode: 191707012
2020-04-29 16:25:08.056 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onNewIntent: SingleTaskActivity taskId: 40489 hashCode: 259974370
2020-04-29 16:25:08.057 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:25:08.058 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onRestart: SingleTaskActivity taskId: 40489 hashCode: 259974370
2020-04-29 16:25:08.058 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleTaskActivity taskId: 40489 hashCode: 259974370
2020-04-29 16:25:08.060 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleTaskActivity taskId: 40489 hashCode: 259974370
2020-04-29 16:25:08.400 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onStop: OtherTaskActivity taskId: 40489 hashCode: 191707012
2020-04-29 16:25:08.401 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onDestroy: OtherTaskActivity taskId: 40489 hashCode: 191707012- 2020-04-29 16:25:08.950 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onPause: SingleTaskActivity taskId: 40489 hashCode: 259974370
2020-04-29 16:25:08.951 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onNewIntent: SingleTaskActivity taskId: 40489 hashCode: 259974370
2020-04-29 16:25:08.953 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:25:08.955 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleTaskActivity taskId: 40489 hashCode: 259974370- 2020-04-29 16:25:10.130 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onPause: SingleTaskActivity taskId: 40489 hashCode: 259974370
2020-04-29 16:25:10.132 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onNewIntent: SingleTaskActivity taskId: 40489 hashCode: 259974370
2020-04-29 16:25:10.134 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:25:10.136 13514-13514/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleTaskActivity taskId: 40489 hashCode: 259974370
当我们从MainActiviyty进入到SingleTaskActivity,再进入到OtherTaskActivity后,此时栈中有3个Activity实例,并且SingleTaskActivity不在栈顶,而在OtherTaskActivity跳到SingleTaskActivity时,并没有创建一个新的SingleTaskActivity,而是复用了该实例,并且回调了onNewIntent方法。并且原来的OtherTaskActivity出栈了,具体见下面的信息,使用命令adb shell dumpsys activity activities可进行查看
- TaskRecord{e5a85ca #40489 A=com.lyf.launchmodektdemo U=0 StackId=1 sz=2}
Run #2: ActivityRecord{2a5292c u0 com.lyf.launchmodektdemo/.SingleTaskActivity t40489}
Run #1: ActivityRecord{f9f926b u0 com.lyf.launchmodektdemo/.MainActivity t40489}
可以看到当前栈中只有两个Activity,即原来栈中位于SingleTaskActivity 之上的Activity都出栈了。
我们看到使用singleTask启动模式启动一个Activity,它还是在原来的task中启动。其实是这样的,我们并没有指定taskAffinity属性,这说明和默认值一样,也就是包名,当MainActivity启动时创建的Task的名字就是包名,因为MainActivity也没有指定taskAffinity,而当我们启动SingleTaskActivity ,首先会寻找需要的任务栈是否存在,也就是taskAffinity指定的值,这里就是包名,发现存在,就不再创建新的task,而是直接使用。当该task中存在该Activity实例时就会复用该实例,这就是栈内复用模式。
这时候,如果我们指定SingleTaskActivity 的taskAffinity值。
- <activity
- android:name=".SingleTaskActivity"
- android:launchMode="singleTask"
- android:taskAffinity="com.lyf.test.singleTask" />
- 这时候,如果我们指定SingleTaskActivity 的taskAffinity值。
- 2020-04-29 16:49:33.424 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onRestart: MainActivity taskId: 40512 hashCode: 240024050
2020-04-29 16:49:33.429 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStart: MainActivity taskId: 40512 hashCode: 240024050
2020-04-29 16:49:33.437 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onResume: MainActivity taskId: 40512 hashCode: 240024050- 2020-04-29 16:49:36.714 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onPause: MainActivity taskId: 40512 hashCode: 240024050
2020-04-29 16:49:36.781 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onCreate: SingleTaskActivity taskId: 40515 hashCode: 60225666
2020-04-29 16:49:36.781 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.test.singleTask
2020-04-29 16:49:36.794 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleTaskActivity taskId: 40515 hashCode: 60225666
2020-04-29 16:49:36.798 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleTaskActivity taskId: 40515 hashCode: 60225666
2020-04-29 16:49:37.336 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: MainActivity taskId: 40512 hashCode: 240024050
2020-04-29 16:49:37.337 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStop: MainActivity taskId: 40512 hashCode: 240024050- 2020-04-29 16:49:39.118 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onPause: SingleTaskActivity taskId: 40515 hashCode: 60225666
2020-04-29 16:49:39.147 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onCreate: OtherTaskActivity taskId: 40515 hashCode: 176277901
2020-04-29 16:49:39.148 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:49:39.155 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStart: OtherTaskActivity taskId: 40515 hashCode: 176277901
2020-04-29 16:49:39.158 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onResume: OtherTaskActivity taskId: 40515 hashCode: 176277901
2020-04-29 16:49:39.479 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: SingleTaskActivity taskId: 40515 hashCode: 60225666
2020-04-29 16:49:39.481 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStop: SingleTaskActivity taskId: 40515 hashCode: 60225666- 2020-04-29 16:49:42.322 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onPause: OtherTaskActivity taskId: 40515 hashCode: 176277901
2020-04-29 16:49:42.332 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onNewIntent: SingleTaskActivity taskId: 40515 hashCode: 60225666
2020-04-29 16:49:42.333 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.test.singleTask
2020-04-29 16:49:42.333 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onRestart: SingleTaskActivity taskId: 40515 hashCode: 60225666
2020-04-29 16:49:42.334 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleTaskActivity taskId: 40515 hashCode: 60225666
2020-04-29 16:49:42.335 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleTaskActivity taskId: 40515 hashCode: 60225666
2020-04-29 16:49:42.679 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStop: OtherTaskActivity taskId: 40515 hashCode: 176277901
2020-04-29 16:49:42.680 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onDestroy: OtherTaskActivity taskId: 40515 hashCode: 176277901- 2020-04-29 16:49:44.245 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onPause: SingleTaskActivity taskId: 40515 hashCode: 60225666
2020-04-29 16:49:44.245 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onNewIntent: SingleTaskActivity taskId: 40515 hashCode: 60225666
2020-04-29 16:49:44.246 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.test.singleTask
2020-04-29 16:49:44.249 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleTaskActivity taskId: 40515 hashCode: 60225666
我们看到SingleTaskActivity所属的任务栈的TaskId发生了变化,也就是说开启了一个新的Task,并且之后的OtherActivity也运行在了该Task上 。
打印出信息也证明了存在两个不同的Task:
- TaskRecord{babe221 #40515 A=com.lyf.test.singleTask U=0 StackId=1 sz=1}
Run #2: ActivityRecord{c1d7e91 u0 com.lyf.launchmodektdemo/.SingleTaskActivity t40515}
TaskRecord{eb83944 #40512 A=com.lyf.launchmodektdemo U=0 StackId=1 sz=1}
Run #1: ActivityRecord{94299af u0 com.lyf.launchmodektdemo/.MainActivity t40512}
如果我们指定SingleTaskActivity的taskAffinity属性与MainActivity一样,又会出现什么情况呢?
配置形式:
- <activity
- android:name=".SingleTaskActivity"
- android:launchMode="singleTask"
- android:taskAffinity="com.lyf.test.launchmodedemo" />
没错,就是和他们什么都不指定是一样的。
这时候,就有了下面的结论
singleTask启动模式启动Activity时,首先会根据taskAffinity去寻找当前是否存在一个对应名字的任务栈
- 如果不存在,则会创建一个新的Task,并创建新的Activity实例入栈到新创建的Task中去
- 如果存在,则得到该任务栈,查找该任务栈中是否存在该Activity实例
如果存在该实例,则将它上面的Activity实例都出栈,然后回调启动的Activity实例的onNewIntent方法
如果不存在该实例,则新建Activity,并入栈
此外,我们可以将两个不同App中的Activity设置为相同的taskAffinity,这样虽然在不同的应用中,但是Activity会被分配到同一个Task中去。
我们再创建另外一个应用,指定它的taskAffinity和之前的一样,都是com.lyf.test.singleTask
- <activity
android:name=".OtherSingleTaskActivity"
android:launchMode="singleTask"
android:taskAffinity="com.lyf.test.singleTask" />
注意:新应用的activity也应设置为singleTask模式。否则效果是不一样的。
先启动一个应用,让他跳转到该Activity后,再按home键让该应用在后台运行,然后启动另一个应用再进入栈内单例Activity,看日志
- 2020-04-29 16:28:55.725 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onCreate: MainActivity taskId: 40496 hashCode: 223658940
2020-04-29 16:28:55.726 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:28:55.760 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onStart: MainActivity taskId: 40496 hashCode: 223658940
2020-04-29 16:28:55.766 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onResume: MainActivity taskId: 40496 hashCode: 223658940- 2020-04-29 16:29:02.961 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onPause: MainActivity taskId: 40496 hashCode: 223658940
2020-04-29 16:29:03.025 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onCreate: SingleTaskActivity taskId: 40497 hashCode: 87000641
2020-04-29 16:29:03.025 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.test.singleTask
2020-04-29 16:29:03.036 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleTaskActivity taskId: 40497 hashCode: 87000641
2020-04-29 16:29:03.040 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleTaskActivity taskId: 40497 hashCode: 87000641
2020-04-29 16:29:03.596 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: MainActivity taskId: 40496 hashCode: 223658940
2020-04-29 16:29:03.597 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onStop: MainActivity taskId: 40496 hashCode: 223658940
- 2020-04-29 16:29:27.895 14457-14457/com.lyf.singletaskdemo I/LaunchMode: *****onCreate()方法*****
2020-04-29 16:29:27.896 14457-14457/com.lyf.singletaskdemo I/LaunchMode: onCreate: MainActivity taskId: 40499 hashCode: 194327709
2020-04-29 16:29:27.896 14457-14457/com.lyf.singletaskdemo I/LaunchMode: taskAffinity: com.lyf.singletaskdemo
2020-04-29 16:29:27.904 14457-14457/com.lyf.singletaskdemo I/LaunchMode: *****onStart()方法*****
2020-04-29 16:29:27.908 14457-14457/com.lyf.singletaskdemo I/LaunchMode: *****onResume()方法*****- 2020-04-29 16:29:30.703 14457-14457/com.lyf.singletaskdemo I/LaunchMode: *****onCreate()方法*****
2020-04-29 16:29:30.704 14457-14457/com.lyf.singletaskdemo I/LaunchMode: onCreate: SingleTaskActivity taskId: 40497 hashCode: 34523045
2020-04-29 16:29:30.704 14457-14457/com.lyf.singletaskdemo I/LaunchMode: taskAffinity: com.lyf.test.singleTask
2020-04-29 16:29:30.710 14457-14457/com.lyf.singletaskdemo I/LaunchMode: *****onStart()方法*****
2020-04-29 16:29:30.715 14457-14457/com.lyf.singletaskdemo I/LaunchMode: *****onResume()方法*****
我们看到,指定了相同的taskAffinity的SingleTaskActivity和OtherActivityActivity被启动到了同一个task中,taskId都为40497。
- TaskRecord{70a40f7 #40497 A=com.lyf.test.singleTask U=0 StackId=1 sz=2}
Run #4: ActivityRecord{e30ad3f u0 com.lyf.singletaskdemo/.SingleTaskActivity t40497}
TaskRecord{c17f593 #40499 A=com.lyf.singletaskdemo U=0 StackId=1 sz=1}
Run #3: ActivityRecord{c7f6489 u0 com.lyf.singletaskdemo/.MainActivity t40499}
TaskRecord{70a40f7 #40497 A=com.lyf.test.singleTask U=0 StackId=1 sz=2}
Run #2: ActivityRecord{d7c5801 u0 com.lyf.launchmodektdemo/.SingleTaskActivity t40497}
TaskRecord{703dc9 #40496 A=com.lyf.launchmodektdemo U=0 StackId=1 sz=1}
Run #1: ActivityRecord{5f830e4 u0 com.lyf.launchmodektdemo/.MainActivity t40496}
四、singleInstance——全局单例模式
这种模式下的Activity会单独占用一个Task栈,具有全局唯一性,即整个系统中就这么一个实例,由于栈内复用的特性,后续的请求均不会创建新的Activity实例,除非这个特殊的任务栈被销毁了。以singleInstance模式启动的Activity在整个系统中是单例的,如果在启动这样的Activity时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。
配置形式:
- <activity
- android:name=".SingleInstanceActivity"
- android:launchMode="singleInstance">
- <intent-filter>
- <action android:name="com.lyf.test.singleinstancedemo" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
使用案例:
- package com.lyf.launchmodektdemo
- import android.os.Bundle
import kotlinx.android.synthetic.main.activity_single_instance.*- class SingleInstanceActivity : BaseActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_single_instance)- btn_self.setOnClickListener {
toActivity<SingleInstanceActivity>()
}- btn_instance.setOnClickListener {
toActivity<OtherInstanceActivity>()
// toActivity<MainActivity>()
}
}
}
现在我们先不指定任何taskAffinity属性,对它做类似singleTask的操作,即从入口MainActivity进入SingleInstanceActivity,然后跳到OtherInstanceActivity,再跳回到SingleInstanceActivity,然后再启动一次SingleInstanceActivity。看看整个过程的日志。
- 2020-04-29 16:33:31.542 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onCreate: MainActivity taskId: 40501 hashCode: 252960824
2020-04-29 16:33:31.542 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:33:31.560 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onStart: MainActivity taskId: 40501 hashCode: 252960824
2020-04-29 16:33:31.564 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onResume: MainActivity taskId: 40501 hashCode: 252960824- 2020-04-29 16:33:33.366 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onPause: MainActivity taskId: 40501 hashCode: 252960824
2020-04-29 16:33:33.417 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onCreate: SingleInstanceActivity taskId: 40502 hashCode: 196024178
2020-04-29 16:33:33.417 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:33:33.427 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleInstanceActivity taskId: 40502 hashCode: 196024178
2020-04-29 16:33:33.431 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleInstanceActivity taskId: 40502 hashCode: 196024178
2020-04-29 16:33:33.989 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: MainActivity taskId: 40501 hashCode: 252960824
2020-04-29 16:33:33.990 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onStop: MainActivity taskId: 40501 hashCode: 252960824- 2020-04-29 16:33:36.899 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onPause: SingleInstanceActivity taskId: 40502 hashCode: 196024178
2020-04-29 16:33:36.939 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onCreate: OtherInstanceActivity taskId: 40501 hashCode: 59304459
2020-04-29 16:33:36.939 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:33:36.945 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onStart: OtherInstanceActivity taskId: 40501 hashCode: 59304459
2020-04-29 16:33:36.948 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onResume: OtherInstanceActivity taskId: 40501 hashCode: 59304459
2020-04-29 16:33:37.599 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: SingleInstanceActivity taskId: 40502 hashCode: 196024178
2020-04-29 16:33:37.601 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onStop: SingleInstanceActivity taskId: 40502 hashCode: 196024178- 2020-04-29 16:33:39.966 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onPause: OtherInstanceActivity taskId: 40501 hashCode: 59304459
2020-04-29 16:33:39.991 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onNewIntent: SingleInstanceActivity taskId: 40502 hashCode: 196024178
2020-04-29 16:33:39.991 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:33:39.992 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onRestart: SingleInstanceActivity taskId: 40502 hashCode: 196024178
2020-04-29 16:33:39.993 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleInstanceActivity taskId: 40502 hashCode: 196024178
2020-04-29 16:33:39.995 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleInstanceActivity taskId: 40502 hashCode: 196024178
2020-04-29 16:33:40.620 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: OtherInstanceActivity taskId: 40501 hashCode: 59304459
2020-04-29 16:33:40.622 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onStop: OtherInstanceActivity taskId: 40501 hashCode: 59304459- 2020-04-29 16:33:43.046 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onPause: SingleInstanceActivity taskId: 40502 hashCode: 196024178
2020-04-29 16:33:43.046 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onNewIntent: SingleInstanceActivity taskId: 40502 hashCode: 196024178
2020-04-29 16:33:43.047 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:33:43.049 14220-14220/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleInstanceActivity taskId: 40502 hashCode: 196024178
当我们从MainActiviyty进入到SingleInstanceActivity,再进入到OtherInstanceActivity后,此时栈中有3个Activity实例,SingleInstanceActivity单独在一个Task中,而从OtherInstanceActivity跳到SingleInstanceActivity时,并没有创建一个新的SingleInstanceActivity,而是复用了该实例,并且回调了onNewIntent方法。并且原来的OtherInstanceActivity没有出栈,具体见下面的信息,使用命令adb shell dumpsys activity activities可进行查看
- TaskRecord{c2d2bf5 #40502 A=com.lyf.launchmodektdemo U=0 StackId=1 sz=1}
Run #3: ActivityRecord{a002f8d u0 com.lyf.launchmodektdemo/.SingleInstanceActivity t40502}
TaskRecord{9de7ffb #40501 A=com.lyf.launchmodektdemo U=0 StackId=1 sz=2}
Run #2: ActivityRecord{c4a3bae u0 com.lyf.launchmodektdemo/.OtherInstanceActivity t40501}
Run #1: ActivityRecord{28990d4 u0 com.lyf.launchmodektdemo/.MainActivity t40501}
可以看到当前栈中只有三个Activity。
我们看到使用singleInstance启动模式启动一个Activity,它创建了一个新的task。
这时候,如果我们指定SingleInstanceActivity 的taskAffinity值。
- <activity
- android:name=".SingleInstanceActivity"
- android:launchMode="singleInstance"
- android:taskAffinity="com.lyf.test.singleInstance">
- <intent-filter>
- <action android:name="com.lyf.test.singleinstancedemo" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
执行上述同样的操作:
- 2020-04-29 16:36:52.237 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onCreate: MainActivity taskId: 40506 hashCode: 184844997
2020-04-29 16:36:52.238 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:36:52.257 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onStart: MainActivity taskId: 40506 hashCode: 184844997
2020-04-29 16:36:52.261 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onResume: MainActivity taskId: 40506 hashCode: 184844997- 2020-04-29 16:36:54.081 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onPause: MainActivity taskId: 40506 hashCode: 184844997
2020-04-29 16:36:54.146 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onCreate: SingleInstanceActivity taskId: 40507 hashCode: 150301101
2020-04-29 16:36:54.147 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.test.singleinstancedemo
2020-04-29 16:36:54.160 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleInstanceActivity taskId: 40507 hashCode: 150301101
2020-04-29 16:36:54.165 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleInstanceActivity taskId: 40507 hashCode: 150301101
2020-04-29 16:36:54.707 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: MainActivity taskId: 40506 hashCode: 184844997
2020-04-29 16:36:54.708 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onStop: MainActivity taskId: 40506 hashCode: 184844997- 2020-04-29 16:36:56.430 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onPause: SingleInstanceActivity taskId: 40507 hashCode: 150301101
2020-04-29 16:36:56.480 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onCreate: OtherInstanceActivity taskId: 40506 hashCode: 114298043
2020-04-29 16:36:56.481 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:36:56.488 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onStart: OtherInstanceActivity taskId: 40506 hashCode: 114298043
2020-04-29 16:36:56.492 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onResume: OtherInstanceActivity taskId: 40506 hashCode: 114298043
2020-04-29 16:36:57.137 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: SingleInstanceActivity taskId: 40507 hashCode: 150301101
2020-04-29 16:36:57.140 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onStop: SingleInstanceActivity taskId: 40507 hashCode: 150301101- 2020-04-29 16:36:59.056 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onPause: OtherInstanceActivity taskId: 40506 hashCode: 114298043
2020-04-29 16:36:59.080 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onNewIntent: SingleInstanceActivity taskId: 40507 hashCode: 150301101
2020-04-29 16:36:59.081 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.test.singleinstancedemo
2020-04-29 16:36:59.081 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onRestart: SingleInstanceActivity taskId: 40507 hashCode: 150301101
2020-04-29 16:36:59.082 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleInstanceActivity taskId: 40507 hashCode: 150301101
2020-04-29 16:36:59.083 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleInstanceActivity taskId: 40507 hashCode: 150301101
2020-04-29 16:36:59.706 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: OtherInstanceActivity taskId: 40506 hashCode: 114298043
2020-04-29 16:36:59.709 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onStop: OtherInstanceActivity taskId: 40506 hashCode: 114298043- 2020-04-29 16:37:01.231 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onPause: SingleInstanceActivity taskId: 40507 hashCode: 150301101
2020-04-29 16:37:01.232 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onNewIntent: SingleInstanceActivity taskId: 40507 hashCode: 150301101
2020-04-29 16:37:01.234 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.test.singleinstancedemo
2020-04-29 16:37:01.238 15405-15405/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleInstanceActivity taskId: 40507 hashCode: 150301101
- TaskRecord{ec31552 #40507 A=com.lyf.test.singleinstancedemo U=0 StackId=1 sz=1}
Run #3: ActivityRecord{68ce1ba u0 com.lyf.launchmodektdemo/.SingleInstanceActivity t40507}
TaskRecord{3a472d9 #40506 A=com.lyf.launchmodektdemo U=0 StackId=1 sz=2}
Run #2: ActivityRecord{b6d1c71 u0 com.lyf.launchmodektdemo/.OtherInstanceActivity t40506}
Run #1: ActivityRecord{fd90bd5 u0 com.lyf.launchmodektdemo/.MainActivity t40506}
除了SingleInstanceActivity的taskAffinity变化之后,其他的结果与不指定taskAffinity是一样的。singleInstance的优先级大于taskAffinity,所以同时指定它们的时候也会按照singleInstance的设置得到对应的结果。
使用下面的方式分别在两个应用中启动它
- Intent singleInstanceIntent = new Intent();
- singleInstanceIntent.setAction("com.lyf.test.singleinstancedemo");
- startActivity(singleInstanceIntent);
操作和上一个(使用两个app操作)一样,日志如下:
第一个应用启动,并跳转到singleInstance模式的Activity
- 2020-04-29 16:39:39.628 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onCreate: MainActivity taskId: 40512 hashCode: 240024050
2020-04-29 16:39:39.629 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
2020-04-29 16:39:39.651 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStart: MainActivity taskId: 40512 hashCode: 240024050
2020-04-29 16:39:39.655 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onResume: MainActivity taskId: 40512 hashCode: 240024050- 2020-04-29 16:39:41.507 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onPause: MainActivity taskId: 40512 hashCode: 240024050
2020-04-29 16:39:41.556 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onCreate: SingleInstanceActivity taskId: 40513 hashCode: 240431118
2020-04-29 16:39:41.557 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.test.singleinstancedemo
2020-04-29 16:39:41.566 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleInstanceActivity taskId: 40513 hashCode: 240431118
2020-04-29 16:39:41.569 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleInstanceActivity taskId: 40513 hashCode: 240431118
2020-04-29 16:39:42.129 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: MainActivity taskId: 40512 hashCode: 240024050
2020-04-29 16:39:42.131 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStop: MainActivity taskId: 40512 hashCode: 240024050
第二个应用启动,尚未跳转
- 2020-04-29 16:40:19.340 16264-16264/com.lyf.singleinstancedemo I/LaunchMode: *****onCreate()方法*****
- 2020-04-29 16:40:19.341 16264-16264/com.lyf.singleinstancedemo I/LaunchMode: onCreate: MainActivity taskId: 40514 hashCode: 153400740
- 2020-04-29 16:40:19.341 16264-16264/com.lyf.singleinstancedemo I/LaunchMode: taskAffinity: com.lyf.singleinstancedemo
- 2020-04-29 16:40:19.355 16264-16264/com.lyf.singleinstancedemo I/LaunchMode: *****onStart()方法*****
- 2020-04-29 16:40:19.359 16264-16264/com.lyf.singleinstancedemo I/LaunchMode: *****onResume()方法*****
第二个应用启动,并跳转到singleInstance模式的Activity
- 2020-04-29 16:39:39.628 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onCreate: MainActivity taskId: 40512 hashCode: 240024050
- 2020-04-29 16:39:39.629 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.launchmodektdemo
- 2020-04-29 16:39:39.651 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStart: MainActivity taskId: 40512 hashCode: 240024050
- 2020-04-29 16:39:39.655 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onResume: MainActivity taskId: 40512 hashCode: 240024050
- 2020-04-29 16:39:41.507 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onPause: MainActivity taskId: 40512 hashCode: 240024050
- 2020-04-29 16:39:41.556 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onCreate: SingleInstanceActivity taskId: 40513 hashCode: 240431118
- 2020-04-29 16:39:41.557 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.test.singleinstancedemo
- 2020-04-29 16:39:41.566 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleInstanceActivity taskId: 40513 hashCode: 240431118
- 2020-04-29 16:39:41.569 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleInstanceActivity taskId: 40513 hashCode: 240431118
- 2020-04-29 16:39:42.129 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: MainActivity taskId: 40512 hashCode: 240024050
- 2020-04-29 16:39:42.131 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStop: MainActivity taskId: 40512 hashCode: 240024050
- 2020-04-29 16:40:16.810 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onPause: SingleInstanceActivity taskId: 40513 hashCode: 240431118
- 2020-04-29 16:40:16.819 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onSaveInstanceState: SingleInstanceActivity taskId: 40513 hashCode: 240431118
- 2020-04-29 16:40:16.823 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStop: SingleInstanceActivity taskId: 40513 hashCode: 240431118
- 2020-04-29 16:40:31.888 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onNewIntent: SingleInstanceActivity taskId: 40513 hashCode: 240431118
- 2020-04-29 16:40:31.889 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: taskAffinity: com.lyf.test.singleinstancedemo
- 2020-04-29 16:40:31.892 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onRestart: SingleInstanceActivity taskId: 40513 hashCode: 240431118
- 2020-04-29 16:40:31.893 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onStart: SingleInstanceActivity taskId: 40513 hashCode: 240431118
- 2020-04-29 16:40:31.897 16149-16149/com.lyf.launchmodektdemo I/LaunchMode: onResume: SingleInstanceActivity taskId: 40513 hashCode: 240431118
我们看到,第一次应用启动SingleInstanceActivity时,由于系统中不存在该实例,所以新建了一个Task,按home键后,使用另一个App进入该Activity,由于系统中已经存在了一个实例,不会再创建新的Task,直接复用该实例,并且回调onNewIntent方法。可以从他们的hashcode中可以看出这是同一个实例。因此我们可以理解为:SingleInstance模式启动的Activity在系统中具有全局唯一性。
- TaskRecord{508550a #40513 A=com.lyf.test.singleinstancedemo U=0 StackId=1 sz=1}
Run #3: ActivityRecord{82b4336 u0 com.lyf.launchmodektdemo/.SingleInstanceActivity t40513}
TaskRecord{a3d9ff1 #40514 A=com.lyf.singleinstancedemo U=0 StackId=1 sz=1}
Run #2: ActivityRecord{80e980 u0 com.lyf.singleinstancedemo/.MainActivity t40514}
TaskRecord{eb83944 #40512 A=com.lyf.launchmodektdemo U=0 StackId=1 sz=1}
Run #1: ActivityRecord{94299af u0 com.lyf.launchmodektdemo/.MainActivity t40512}
git源码:https://github.com/First-Time/LaunchModeKTDemo.git
Activity四大启动模式的更多相关文章
- 彻底弄懂Activity四大启动模式
最近有几位朋友给我留言,让我谈一下对Activity启动模式的理解.我觉得对某个知识点的理解必须要动手操作才能印象深刻,所以今天写一篇博文,结合案例理解Activity启动模式.由于之前看过" ...
- Android中Activity的四大启动模式实验简述
作为Android四大组件之一,Activity可以说是最基本也是最常见的组件,它提供了一个显示界面,从而实现与用户的交互,作为初学者,必须熟练掌握.今天我们就来通过实验演示,来帮助大家理解Activ ...
- Activity LauchMode启动模式(转载)
转载于:http://www.cnblogs.com/plokmju/p/android_ActivityLauncherMode.html 在一个Android应用中,不可避免的会包含多个Activ ...
- Android开发艺术2之Activity的启动模式
Activity是Android的四大组件之一,他的重要性毋庸置疑,对于这么重要的一个组件,我们首先要知道这些都是由系统进行管理和回调的,要理解Activity的启动模式,我们首先来了解一下Andro ...
- Activity的启动模式--总结
3. Activity的任务栈Task以及启动模式与Intent的Flag详解? 2,Activity次级页面和主页间来回跳转,防止重复创建Activity实例 1, activity的启动模式: / ...
- 关于activity的启动模式
在Android中每个界面都是一个Activity ,界面的切换实际上是对不同Activity实例化的过程.而启动模式就决定Activity启动运行方式. 1.设置方式它是在主配置文件中,Activi ...
- 无废话Android之activity的生命周期、activity的启动模式、activity横竖屏切换的生命周期、开启新的activity获取他的返回值、利用广播实现ip拨号、短信接收广播、短信监听器(6)
1.activity的生命周期 这七个方法定义了Activity的完整生命周期.实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环: (1)Activity的完整生命周期 自第一次调用onCrea ...
- android Activity的启动模式与flag的见解
最近做一个安卓项目,想要实现的效果就是:当打开一个按钮的时候,启动了一个A功能,当用户返回到桌面再继续进去的时候,不过之前在哪个Activity,都会先跳转到A功能的那个界面,当用户点击返回的时候,再 ...
- android Activity的启动模式
Android中Activity启动模式详解 在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启 ...
随机推荐
- JS、JSP、ASP、CGI
1)JS是在客户端执行的,需要浏览器支持Javascript.JSP是在服务器端执行的,需要服务器上部署支持Servlet的服务器程序.JS代码是能够直接从服务器上download得到,对外是可见 ...
- innodb mvcc多版本实现
出自:http://hedengcheng.com/?p=148 基本知识 假设对于多版本(MVCC)的基础知识,有所了解.InnoDB为了实现多版本的一致读,采用的是基于回滚段的协议. 行结构 In ...
- asp.net 重写URL方法和封装好的DLL
.net 重写URL方法和封装好的DLL URL重写方法DLL(2.0)
- day2(基础数据类型)
一.基础数据类型操作 1.数字 int 数字主要是用于计算用的,使用方法并不是很多,就记住一种就可以: int.bit_length() -> int Number of bits necess ...
- 适配android和iOS上position:absolute和input问题
//适配android上absolute和input的问题var oHeight = $(document).height(); //屏幕当前的高度$(window).resize(function( ...
- Java理论学时第五节。课后作业。
随机生成10个数,填充一个数组,然后用消息框显示数组内容,接着计算数组元素的和,将结果也显示在消息框中. 设计思路:先声明一个数组,再利用for循环对每一个元素赋随机生成的值,在求所有数的和,再根据要 ...
- SSM_CRUD新手练习(2)配置文件
配置之前现需要引入依赖的jar包: *Spring *SpringMvc *Mybatis *数据库连接池,驱动包 *其他(jstl,Servlet ,Junit..) 1.poxm.xml < ...
- SPRING框架中ModelAndView、Model、ModelMap区别及详细分析
转载内容:http://www.cnblogs.com/google4y/p/3421017.html 1. Model Model 是一个接口, 其实现类为ExtendedModelMap,继承了M ...
- SRM478
又是rng_58的神题.. 250pt: 题意:给定一个初始数x,对于这个数可以进行x*4+3,或者x*8+7的操作.最多进行100000次操作 问最少经过几次出现%1000000007 == 0的情 ...
- EBS 取消“是否提交另一项请求”提示
在使用EBS提交请求后,总要弹出“是否提交另一项请求”的提示,而我们往往选择“否”,这个提示就显得多余. 为了减轻这“多一步”的负担,取消“是否提交另一项请求”的提示,设置方法如下: 以下profil ...