• 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种情况

    1. 当前栈中已有该Activity的实例并且该实例位于栈顶时,不会新建实例,而是复用栈顶的实例,并且会将Intent对象传入,回调onNewIntent方法
    2. 当前栈中已有该Activity的实例但是该实例不在栈顶时,其行为和standard启动模式一样,依然会创建一个新的实例
    3. 当前栈中不存在该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

  • 相关阅读:
    [Bada开发]基于bada1.0的5种控件介绍[待续]
    [Bada开发]API官方学习2-风格
    [Bada开发]HelloWorld篇
    [Bada开发]初步入口函数介绍
    [Bada开发]使用共享库
    [Bada开发]使用静态库
    [Bada开发]OpenGL ES 2.0程序 创建简单3D图形
    [Bada开发]播放实时rtsp流
    剑指offer-删除链表中重复的结点
    剑指offer-构建乘积数组
  • 原文地址:https://www.cnblogs.com/diyishijian/p/7705588.html
Copyright © 2020-2023  润新知