[TOC]
在Android中Activity的启动模式是可以自己定义的,可以通过两种方法进行自定义:
- 1.使用清单文件定义:在AndroidManifest中定义Activity元素时用元素的 launchMode属性定义启动模式。
- 2.使用Intent标志定义:在调用startActivity()时,可以在Intent中加入一个标志,用于声明启动模式。
1.使用清单文件定义
在使用清单定义时,可以定义四种启动模式如下: standard(默认模式)、singleTop、singleTask、singleInstance 使用例子如下:
<activity android:name=".standard.StandardActivity"
android:launchMode="standard"/>
如果没有设置==android:launchMode== 默认为standard(默认模式)模式。
1.standard模式(默认模式)
这个模式是默认模式,系统在启动这个模式的Activity的任务中每次都会创建一个新的实例并向其传送Intent。Activity可以多次实例化,而且每个实例均可属于不同的任务,并且一个任务可以拥有多个实例。 如下图所示:

- 在MainActivity中启动一个StandardActivity,系统创建了一个实例并并存入栈中,这时 StandardActivity在堆栈顶部并且显示给用户。
- 在StandardActivity启动一个StandardActivity时系统会在重新创建一个实例并存入堆栈顶部显示给用户,这时堆栈中有两个StandardActivity的实例。
- 用户点击返回时堆栈顶部的第二个StandardActivity被移出堆栈并销毁,这时第一个StandardActivity会在堆栈顶部并向用户展示,用户在点击返回时会返回到MainActivity。 。 以下是运行时的日志:
StandardActivity1 :onCreate 方法-------------------------
StandardActivity1 :onCreate:StandardActivity TaskId:143 TaskNum:2 hasCode:156403808
StandardActivity1:TaskAffinity:com.hugo.reviewbasic
StandardActivity1 :onStart 方法-------------------------
StandardActivity1 :onResume 方法-------------------------
MainActivity :onSaveInstanceState 方法-------------------------
MainActivity :onStop 方法-------------------------
StandardActivity1 :onPause 方法-------------------------
StandardActivity2 :onCreate 方法-------------------------
StandardActivity2 :onCreate:StandardActivity TaskId:143 TaskNum:3 hasCode:15174462
StandardActivity2:TaskAffinity:com.hugo.reviewbasic
StandardActivity2 :onStart 方法-------------------------
StandardActivity2 :onResume 方法-------------------------
StandardActivity1 :onSaveInstanceState 方法-------------------------
StandardActivity1 :onStop 方法-------------------------
StandardActivity2 :onPause 方法-------------------------
StandardActivity1 :onRestart 方法-------------------------
StandardActivity1 :onStart 方法-------------------------
StandardActivity1 :onResume 方法-------------------------
StandardActivity2 :onStop 方法-------------------------
StandardActivity2 :onDestroy 方法-------------------------
StandardActivity1 :onPause 方法-------------------------
MainActivity :onRestart 方法-------------------------
MainActivity :onStart 方法-------------------------
MainActivity :onResume 方法-------------------------
StandardActivity1 :onStop 方法-------------------------
StandardActivity1 :onDestroy 方法-------------------------
这里我们可以看到standard启动模式为:每次启动一个Activity都会重新创建一个新的实例。
2.SingleTop模式(栈顶复用)
这个模式是在当前堆栈的顶部已经存在Activity的一个实例了,则系统在启动这个activity时,系统不会重新去创建一个新的实例,而是直接调用堆栈顶部的onNewIntent()返回向其传送Intent。 在这个模式下 Activity可以多次实例化,而且每个实例均可以属于不同的任务栈,并且一个任务栈都可以拥有多个实例(但是前提是位于栈顶的Activity并不是该Activity的现有实例)。
如下图所示:

- 从MainActivity启动SingleTopActivity,系统会创建一个SingleTopActivity的实例存入堆栈的顶部,并展示给用户。
- 在SingleTopActivity的实例中启动SingleTopActivity,这时由于栈顶的顶部是SingleTopActivity的实例,所以系统不会去重新创建一个实例,而是直接调用 ==onNewIntent()== 方法并传入Intent。
- 在SingleTopActivity的实例中启动OtherTopActivity,这是系统会创建一个OtherTopActivity的实例存入堆栈的顶部,并展示给用户。
- 在OtherTopActivity的实例中启动SingleTopActivity,这是由于栈顶不是SingleTopActivity的实例,所以系统会重新创建一个SingleTopActivity的实例存入栈顶,并展示给用户,而不是直接调用堆栈中的SingleTopActivity实例的onNewIntent()方法。
- 用户点击返回时堆栈会从栈顶一个一个的移出并销毁。
下面是日志:
MainActivity :onPause 方法-------------------------
SingleTopActivity :onCreate 方法-------------------------
SingleTopActivity :onCreate:SingleTopActivity TaskId:145 TaskNum:2 hasCode:156403808
SingleTopActivity:TaskAffinity:com.hugo.reviewbasic
SingleTopActivity :onStart 方法-------------------------
SingleTopActivity :onResume 方法-------------------------
MainActivity :onSaveInstanceState 方法-------------------------
MainActivity :onStop 方法-------------------------
SingleTopActivity :onPause 方法-------------------------
SingleTopActivity :onNewIntent 方法-------------------------
SingleTopActivity :onNewIntent:SingleTopActivity TaskId:145 TaskNum:2 hasCode:156403808
SingleTopActivity:TaskAffinity:com.hugo.reviewbasic
SingleTopActivity :onResume 方法-------------------------
SingleTopActivity :onPause 方法-------------------------
OtherTopActiivty :onCreate 方法-------------------------
OtherTopActiivty :onCreate:OtherTopActiivty TaskId:145 TaskNum:3 hasCode:135228666
OtherTopActiivty:TaskAffinity:com.hugo.reviewbasic
OtherTopActiivty :onStart 方法-------------------------
OtherTopActiivty :onResume 方法-------------------------
SingleTopActivity :onSaveInstanceState 方法-------------------------
SingleTopActivity :onStop 方法-------------------------
OtherTopActiivty :onPause 方法-------------------------
SingleTopActivity :onCreate 方法-------------------------
SingleTopActivity :onCreate:SingleTopActivity TaskId:145 TaskNum:4 hasCode:204001128
SingleTopActivity:TaskAffinity:com.hugo.reviewbasic
SingleTopActivity :onStart 方法-------------------------
SingleTopActivity :onResume 方法-------------------------
OtherTopActiivty :onSaveInstanceState 方法-------------------------
OtherTopActiivty :onStop 方法-------------------------
SingleTopActivity :onPause 方法-------------------------
OtherTopActiivty :onRestart 方法-------------------------
OtherTopActiivty :onStart 方法-------------------------
OtherTopActiivty :onResume 方法-------------------------
SingleTopActivity :onStop 方法-------------------------
SingleTopActivity :onDestroy 方法-------------------------
OtherTopActiivty :onPause 方法-------------------------
SingleTopActivity :onRestart 方法-------------------------
SingleTopActivity :onStart 方法-------------------------
SingleTopActivity :onResume 方法-------------------------
OtherTopActiivty :onStop 方法-------------------------
OtherTopActiivty :onDestroy 方法-------------------------
SingleTopActivity :onPause 方法-------------------------
MainActivity :onRestart 方法-------------------------
MainActivity :onStart 方法-------------------------
MainActivity :onResume 方法-------------------------
SingleTopActivity :onStop 方法-------------------------
SingleTopActivity :onDestroy 方法-------------------------
我们可以看到在SingleTop模式下
- 当前堆栈中已经有了该Activity的实例并且该实例位于堆栈顶部时,启动该Activity不会重新创建实例,而是复用该Activity在栈顶的实例,调用onNewIntent()方法传入Intent。
- 当前堆栈中已经有了该Activity的实例但是该实例不在堆栈顶部时,启动该Activity其行为和standard启动模式是一样的,会重新创建一个新的实例。
- 当前堆栈中没有该Activity的实例时,启动该Activity的行为和Standard启动模式一样。
3.singleTask模式(栈内复用模式)
在这个模式下启动Activity时,如果栈中存在这个Activity的实例就会复用这个实例,不管它是否位于任务栈顶,复用时,会将它之上的所有其他Activity的实例移动任务栈,并且调用该实例的onNewIntent()方法传入Intent。其实在这个过程中还存在一个任务栈的匹配,因为这个模式启动时,会在自己需要的任务栈中寻找实例,这个任务栈是通过taskAffinity属性指定的,如果任务栈不存在,则会创建这个任务栈。
任务栈在Androidmanifest 文件声明Activity是设置 如果没有设置默认为软件包名
任务栈设置如下:
<activity android:name=".singleTask.OtherSingleTaskActivity"
android:launchMode="singleTask"
android:taskAffinity="com.hugo.OtherSingleTaskActivity"
/>
例子步骤如下图:

- 在MainActivity中SingleTask模式启动SingleTaskActivity,由于栈类没有该Activity实例,并且该Activity声明时没有设置任务栈,所以系统创建了一个实例并存入默认任务栈顶部。
- 在SingleTaskActivity中启动一个OtherActivity,OtherActivity为默认启动模式,所以系统创建一个实例并存入默认task中。
- 在OtherActivity中SingleTask模式启动OtherSingleTaskActivity,由于OtherSingleTaskActivity在声明时设置了任务栈,这时该任务栈并没有创建,所以系统会创建新的任务栈并创建OtherSingleTaskActivity存入新的任务栈,然后这个新任务栈会存入back stack(回退栈)顶部。
- 在OtherSingleTaskActivity的实例中默认模式启动一个OtherActivity,系统会创建一个新的实例并存入新任务栈顶部。
- 在新任务栈的OtherActivity实例中启动SingleTaskActivity,由于SingleTaskActivity实例已经存在,所以系统会匹配对应的任务栈(默认任务栈),并找到SingleTaskActivity的实例,调用该实例的onNewIntent()方法传入Intent,并把该任务栈(默认任务栈)移到回退栈的顶部,而任务栈中在该实例之上的Activity实例会被移出任务栈并销毁,而让该实例显示给用户。
- 点击返回,会把SingleTaskActivity实例移出默认任务栈并销毁,使MainActivity实例显示给用户。
- 再次点击返回,会把MainActivity实例移出默认任务栈并销毁,这是默认任务栈已经没有Activity实例了,所以会把新的任务栈中的顶部OtherActivity的实例显示给用户。
- 再次点击返回,会把新任务中的OtherActivity的实例移出任务栈并销毁,把任务栈中的OtherSingleTaskActivity的实例展示给用户。
- 再次点击返回,这时会把任务栈中OtherSingleTaskActivity的实例移出任务栈,并退出APP返回桌面。
以上步骤日志如下:
MainActivity :onPause 方法-------------------- hasCode:26596009
SingleTaskActivity :onCreate 方法-------------------------
SingleTaskActivity :onCreate:SingleTaskActivity hasCode:236910323 TaskId:166 TaskNum:2 TaskAffinity:com.hugo.reviewbasic
SingleTaskActivity :onStart 方法------------------ hasCode:236910323
SingleTaskActivity :onResume 方法-------------------- hasCode:236910323
MainActivity :onSaveInstanceState 方法------------------ hasCode:26596009
MainActivity :onStop 方法------------------- hasCode:26596009
SingleTaskActivity :onPause 方法-------------------- hasCode:236910323
OtherActivity :onCreate 方法-------------------------
OtherActivity :onCreate:OtherActivity hasCode:162823661 TaskId:166 TaskNum:3 TaskAffinity:com.hugo.reviewbasic
OtherActivity :onStart 方法------------------ hasCode:162823661
OtherActivity :onResume 方法-------------------- hasCode:162823661
SingleTaskActivity :onSaveInstanceState 方法------------------ hasCode:236910323
SingleTaskActivity :onStop 方法------------------- hasCode:236910323
OtherActivity :onPause 方法-------------------- hasCode:162823661
OtherSingleTaskActivity :onCreate 方法-------------------------
OtherSingleTaskActivity :onCreate:OtherSingleTaskActivity hasCode:182738289 TaskId:167 TaskNum:1 TaskAffinity:com.hugo.OtherSingleTaskActivity
OtherSingleTaskActivity :onStart 方法------------------ hasCode:182738289
OtherSingleTaskActivity :onResume 方法-------------------- hasCode:182738289
OtherActivity :onSaveInstanceState 方法------------------ hasCode:162823661
OtherActivity :onStop 方法------------------- hasCode:162823661
OtherSingleTaskActivity :onPause 方法-------------------- hasCode:182738289
OtherActivity :onCreate 方法-------------------------
OtherActivity :onCreate:OtherActivity hasCode:123068584 TaskId:167 TaskNum:2 TaskAffinity:com.hugo.reviewbasic
OtherActivity :onStart 方法------------------ hasCode:123068584
OtherActivity :onResume 方法-------------------- hasCode:123068584
OtherSingleTaskActivity :onSaveInstanceState 方法------------------ hasCode:182738289
OtherSingleTaskActivity :onStop 方法------------------- hasCode:182738289
OtherActivity :onDestroy 方法------------------- hasCode:162823661
OtherActivity :onPause 方法-------------------- hasCode:123068584
SingleTaskActivity :onNewIntent 方法-------------------- hasCode:236910323
SingleTaskActivity :onNewIntent:SingleTaskActivity hasCode:236910323 TaskId:166 TaskNum:2 TaskAffinity:com.hugo.reviewbasic
SingleTaskActivity :onRestart 方法------------------- hasCode:236910323
SingleTaskActivity :onStart 方法------------------ hasCode:236910323
SingleTaskActivity :onResume 方法-------------------- hasCode:236910323
OtherActivity :onSaveInstanceState 方法------------------ hasCode:123068584
OtherActivity :onStop 方法------------------- hasCode:123068584
SingleTaskActivity :onPause 方法-------------------- hasCode:236910323
MainActivity :onRestart 方法------------------- hasCode:26596009
MainActivity :onStart 方法------------------ hasCode:26596009
MainActivity :onResume 方法-------------------- hasCode:26596009
SingleTaskActivity :onStop 方法------------------- hasCode:236910323
SingleTaskActivity :onDestroy 方法------------------- hasCode:236910323
MainActivity :onPause 方法-------------------- hasCode:26596009
OtherActivity :onRestart 方法------------------- hasCode:123068584
OtherActivity :onStart 方法------------------ hasCode:123068584
OtherActivity :onResume 方法-------------------- hasCode:123068584
MainActivity :onStop 方法------------------- hasCode:26596009
MainActivity :onDestroy 方法------------------- hasCode:26596009
OtherActivity :onPause 方法-------------------- hasCode:123068584
OtherSingleTaskActivity :onRestart 方法------------------- hasCode:182738289
OtherSingleTaskActivity :onStart 方法------------------ hasCode:182738289
OtherSingleTaskActivity :onResume 方法-------------------- hasCode:182738289
OtherActivity :onStop 方法------------------- hasCode:123068584
OtherActivity :onDestroy 方法------------------- hasCode:123068584
OtherSingleTaskActivity :onPause 方法-------------------- hasCode:182738289
OtherSingleTaskActivity :onStop 方法------------------- hasCode:182738289
OtherSingleTaskActivity :onDestroy 方法------------------- hasCode:182738289
我们可以看到在SingleTask启动模式下
- 启动Activity时会根据taskffinity 去寻找当前是否存在一个对应名字的任务栈,
- 如果存在,则得到该任务栈,在查找任务栈中是否存在该Activity的实例,
- 如果存在实例,就把该任务栈中在该Activity实例之上Activity实例都移出任务栈,然后调用该Activity实例的onNewIntent()返回传入Intent。
- 如果不存在,这新建Activity实例并存入任务栈中。
- 如果不存在,则会创建一个新的任务栈,并创建新的Activity实例并存入新建的任务栈中。
- 如果存在,则得到该任务栈,在查找任务栈中是否存在该Activity的实例,
- 如果我们在两个不同的APP中的Activity设置为相同的TaskAffinity,这样虽然在不同的应用中,但是Activity会被分配到同一个task中去。如下图所示:

日志
com.hugo.wanandroid I/OtherSingleTaskActivity: [hugo] OtherSingleTaskActivity :onCreate:OtherSingleTaskActivity hasCode:153472021 TaskId:210 TaskAffinity:com.hugo.OtherSingleTaskActivity
com.hugo.reviewbasic I/BaseActivity: [hugo] OtherSingleTaskActivity :onCreate:OtherSingleTaskActivity hasCode:97368138 TaskId:210 TaskNum:2 TaskAffinity:com.hugo.OtherSingleTaskActivity
我们可以在图中看到ComponenApp中的一个Activity和我的测试App的OtherSingleTaskActivity 设置在了同一个任务栈 所以在我先打开ComponenApp的Activity按Home键回到桌面在在我的测试App打开OtherSingleTaskActivity 时不会重新创建一个新的任务栈而是获取了ComponenApp启动Activity时创建的任务栈(日志中的==TaskId:210==),并把OtherSingleTaskActivity的实例存入这个任务栈,然后把整个任务移动到回退堆栈的顶部,这时我们点返回后,显示的不是SingleTaskActivity,而是ComponenApp中的Activity,在点击返回时才会返回到SingleTaskActivity,而这是ComponenApp中的Activity也已经被关闭并销毁。
4.SingleInstance模式
这种模式与SingleTask模式基本一样,只是系统不会将任何其他的Activity启动到包含实例的任务栈中,该Activity始终是其任务栈中唯一仅有的成员;由此Activity启动的任何Activity均在其他的任务栈中打开。
如下图所示:

- 在MainActivity中SingleInstance模式启动SingleInstanceActivity中standard模式启动OtherActivity1,由于SingleInstanceActivity没有启动过,所以系统会创建一个新的任务栈task1,然后创建该Activity的实例存入任务栈task1中,并把该任务栈task1存入到回退栈顶。
- 在SingleInstanceActivity所以中standard模式启动OtherActivity1,由于是在SingleInstanceActivity所以OtherActivity1的实例会被系统分配给别的任务栈,这里是分配给了默认任务栈,并把默认任务栈移动到了回退栈的顶部。
- 在OtherActivity1的实例中用SingleInstance模式启动OtherSingleInstanceActivity,由于这是系统中没有OtherSingleInstanceActivity的实例,所以系统会创建一个新的任务栈task2,然后把新建的该Activity的实例存入该任务栈,并把该任务栈移动存入回退栈顶。
- 在OtherSingleInstanceActivity的实例中用Standard模式启动一个OtherActivity1,这时系统会把新创建的OtherActivity1的实例分配给其他的任务栈,这里是分配给了默认任务栈,并把任务栈移动到回退栈顶。
- 在OtherActivity1的实例中启动SingleInstanceActivity,由于SingleInstanceActivity的实例已经存在,所有这时系统会自动去匹配任务栈找到已经存在的实例,并把该任务栈移动到回退栈顶。
- 点击返回,把SingleInstanceActivity的实例从task1任务栈移出并关闭该任务栈,这是在回退栈中默认任务栈到了回退栈顶,所以在默认任务栈顶的OtherActivity1的第二个实例显示给用户。
- 点击返回,从默认任务栈中移出OtherActivity1的第二个实例并销毁,这时由于默认task是在回退栈顶的所以,当OtherActivity1的第二个实例移出栈后显示在前台的是OtherActivity1的第一个实例,而不是OtherSingleInstanceActivity。
- 点击返回,这是会把OtherActivity1的第一个实例移出栈并销毁,然后显示MainActivity。
- 点击返回,会把MainActivity移出栈,这是在默认的task中已经没有了实例,所以默认的task也会被销毁,然后显示回退栈中处于顶部的task2任务栈中的OtherSingleInstanceActivity。
- 点击返回会移出OtherSingleInstanceActivity实例并关闭task2任务栈。退出APP,返回桌面。
提示:如果我们在第10步时用Standard模式启动一个Activity,系统会重新创建一个新的task任务栈来存储该Activity的实例。
下面是按照上面步骤的日志:
MainActivity :onCreate 方法-------------------------
MainActivity :onCreate:MainActivity hasCode:53162219 TaskId:221 TaskNum:1 TaskAffinity:com.hugo.reviewbasic
MainActivity :onStart 方法------------------ hasCode:53162219
MainActivity :onResume 方法-------------------- hasCode:53162219
MainActivity :onPause 方法-------------------- hasCode:53162219
SingleInstanceActivity :onCreate 方法-------------------------
SingleInstanceActivity :onCreate:SingleInstanceActivity hasCode:35048165 TaskId:222 TaskNum:1 TaskAffinity:com.hugo.reviewbasic
SingleInstanceActivity :onStart 方法------------------ hasCode:35048165
SingleInstanceActivity :onResume 方法-------------------- hasCode:35048165
MainActivity :onSaveInstanceState 方法------------------ hasCode:53162219
MainActivity :onStop 方法------------------- hasCode:53162219
SingleInstanceActivity :onPause 方法-------------------- hasCode:35048165
OtherActivity1 :onCreate 方法-------------------------
OtherActivity1 :onCreate:OtherActivity1 hasCode:220012746 TaskId:221 TaskNum:2 TaskAffinity:com.hugo.reviewbasic
OtherActivity1 :onStart 方法------------------ hasCode:220012746
OtherActivity1 :onResume 方法-------------------- hasCode:220012746
SingleInstanceActivity :onSaveInstanceState 方法------------------ hasCode:35048165
SingleInstanceActivity :onStop 方法------------------- hasCode:35048165
OtherActivity1 :onPause 方法-------------------- hasCode:220012746
OtherSingleInstanceActivity :onCreate 方法-------------------------
OtherSingleInstanceActivity :onCreate:OtherSingleInstanceActivity hasCode:245363070 TaskId:223 TaskNum:1 TaskAffinity:con.hugo.instance1
OtherSingleInstanceActivity :onStart 方法------------------ hasCode:245363070
OtherSingleInstanceActivity :onResume 方法-------------------- hasCode:245363070
OtherActivity1 :onSaveInstanceState 方法------------------ hasCode:220012746
OtherActivity1 :onStop 方法------------------- hasCode:220012746
OtherSingleInstanceActivity :onPause 方法-------------------- hasCode:245363070
OtherActivity1 :onCreate 方法-------------------------
OtherActivity1 :onCreate:OtherActivity1 hasCode:87192460 TaskId:221 TaskNum:3 TaskAffinity:com.hugo.reviewbasic
OtherActivity1 :onStart 方法------------------ hasCode:87192460
OtherActivity1 :onResume 方法-------------------- hasCode:87192460
OtherSingleInstanceActivity :onSaveInstanceState 方法------------------ hasCode:245363070
OtherSingleInstanceActivity :onStop 方法------------------- hasCode:245363070
OtherActivity1 :onPause 方法-------------------- hasCode:87192460
SingleInstanceActivity :onNewIntent 方法-------------------- hasCode:35048165
SingleInstanceActivity :onNewIntent:SingleInstanceActivity hasCode:35048165 TaskId:222 TaskNum:1 TaskAffinity:com.hugo.reviewbasic
SingleInstanceActivity :onRestart 方法------------------- hasCode:35048165
SingleInstanceActivity :onStart 方法------------------ hasCode:35048165
SingleInstanceActivity :onResume 方法-------------------- hasCode:35048165
OtherActivity1 :onSaveInstanceState 方法------------------ hasCode:87192460
OtherActivity1 :onStop 方法------------------- hasCode:87192460
SingleInstanceActivity :onPause 方法-------------------- hasCode:35048165
OtherActivity1 :onRestart 方法------------------- hasCode:87192460
OtherActivity1 :onStart 方法------------------ hasCode:87192460
OtherActivity1 :onResume 方法-------------------- hasCode:87192460
SingleInstanceActivity :onStop 方法------------------- hasCode:35048165
SingleInstanceActivity :onDestroy 方法------------------- hasCode:35048165
OtherActivity1 :onPause 方法-------------------- hasCode:87192460
OtherActivity1 :onRestart 方法------------------- hasCode:220012746
OtherActivity1 :onStart 方法------------------ hasCode:220012746
OtherActivity1 :onResume 方法-------------------- hasCode:220012746
OtherActivity1 :onStop 方法------------------- hasCode:87192460
OtherActivity1 :onDestroy 方法------------------- hasCode:87192460
OtherActivity1 :onPause 方法-------------------- hasCode:220012746
MainActivity :onRestart 方法------------------- hasCode:53162219
MainActivity :onStart 方法------------------ hasCode:53162219
MainActivity :onResume 方法-------------------- hasCode:53162219
OtherActivity1 :onStop 方法------------------- hasCode:220012746
OtherActivity1 :onDestroy 方法------------------- hasCode:220012746
MainActivity :onPause 方法-------------------- hasCode:53162219
OtherSingleInstanceActivity :onRestart 方法------------------- hasCode:245363070
OtherSingleInstanceActivity :onStart 方法------------------ hasCode:245363070
OtherSingleInstanceActivity :onResume 方法-------------------- hasCode:245363070
MainActivity :onStop 方法------------------- hasCode:53162219
MainActivity :onDestroy 方法------------------- hasCode:53162219
OtherSingleInstanceActivity :onPause 方法-------------------- hasCode:245363070
OtherSingleInstanceActivity :onStop 方法------------------- hasCode:245363070
OtherSingleInstanceActivity :onDestroy 方法------------------- hasCode:245363070
可以看出SingleInstance启动模式基本和SingleTask一致,区别就是SingleInstance的栈类只能存在一个本身实例,不能存在其他Activity的实例,而SingleTask的栈内可以存在其他Activity的实例。
下面是官方的说明:
| 用例 | 启动模式 | 多个实例? | 注释 |
|---|---|---|---|
| 大多数 Activity 的正常启动 | “standard” |
是 | 默认值。系统始终会在目标任务中创建新的 Activity 实例并向其传送 Intent。 |
“singleTop” |
有条件 | 如果目标任务的顶部已存在一个 Activity 实例,则系统会通过调用该实例的 onNewIntent() 方法向其传送 Intent,而不是创建新的 Activity 实例。 |
|
| 专用启动 (不建议用作常规用途) |
“singleTask” |
否 | 系统在新任务的根位置创建 Activity 并向其传送 Intent。
不过,如果已存在一个 Activity 实例,则系统会通过调用该实例的 onNewIntent() 方法向其传送 Intent,而不是创建新的 Activity 实例。 |
“singleInstance” |
否 | 与“singleTask"”相同,只是系统不会将任何其他 Activity 启动到包含实例的任务中。
该 Activity 始终是其任务唯一仅有的成员。 |
2.使用Intent标志
使用Intent标志返回设置启动模式可以是用多种标志本文只简介其中比较长用的几种,想知道更多请点击 这个链接 查看。
使用例子如下:
val intent =Intent(this,SingleInstanceActivity::class.java)
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
1. FLAG_ACTIVITY_NEW_TASK
在新任务中启动Activity。如果该Activity已经启动,则该Activity所在的任务转到前台并恢复其最后状态,同时调用 ==onNewIntent()== 返回传入Intent。
这个标志会和前文中 清单设置launchMode 的“SingleTask” 的行为相同。
2. FLAG_ACTIVITY_SINGLE_TOP
如果正在启动的Activity是当前Activity(位于返回栈的顶部),则回调现有实例调用 ==onNewIntent()== 方法传入Intent,而不会创建新的实例。
这个标志和前文中 清单设置launchMode 的 “SingleTop” 的行为相同。
3. FLAG_ACTIVITY_CLEAR_TOP
如果正在启动的Activity已在当前任务中运行,则会销毁当前任务顶部的所有Activity,并通过 onNewIntent() 返回键Intent传递给该Activity的实例(现在位于顶部),而不是启动该Activity的新实例。
如果该Activity在其他任务栈中已有实例或没有实例,但是在当前任务栈中没有,那么系统会重新创建一个实例存入当前任务栈中。
如果启动的Activity 的启动模式为“Standard”,则该Activity也会从堆栈中移除销毁,并在其位置重新创建一个新实例,以便处理传入的Intent。这是因为当启动模式为“Standard”时,将始终为新Intent创建新实例。
3.关于关联的配置(taskAffinity)
“关联”是用于指示Activity优先属于那个任务栈,默认情况下,同一应用中的所有Activity彼此关联。因此,默认情况下,同一应用中的所有Activity优先位于相同任务中。不过可以修改Activity的默认关联。在不同应用中定义的Activity可以共享关联,或者可以在同一个应用中定义的Activity分配不同的任务关联。
设置如下:
<activity android:name=".singleInstance.OtherSingleInstanceActivity"
android:launchMode="singleInstance"
android:taskAffinity="con.hugo.instance1"/>
- 系统的默认关联为应用包名。
- 我们可以单独为每一个Activity指定关联。
- 在概念上,具有相同关联的Activity(即设置了相同taskAffinity属性的Activity)属于同一个任务。
- 为一个Activity的taskAffinity设置为空字符串,表面这个Activity不属于任何task。
4.启动关于5.0以下startActivityForResult()的问题
在Android5.0以前使用startActivityForResult() 启动 SingleTask 和SingleInstance 模式的Activity 会出现 一启动就在onActivityResult()方法中收到回调的问题 日志如下:
MainActivity :onPause 方法-------------------- hasCode:-1660511584
MainActivity :onActivityResult 获取数据:null requestCode:10001
MainActivity :onResume 方法-------------------- hasCode:-1660511584
MainActivity :onPause 方法-------------------- hasCode:-1660511584
SingleTaskActivity :onCreate 方法-------------------------
SingleTaskActivity :onCreate:SingleTaskActivity hasCode:-1659844560 TaskId:9 TaskNum:-1 TaskAffinity:com.hugo.reviewbasic
SingleTaskActivity :onStart 方法------------------ hasCode:-1659844560
SingleTaskActivity :onResume 方法-------------------- hasCode:-1659844560
MainActivity :onSaveInstanceState 方法------------------ hasCode:-1660511584
MainActivity :onStop 方法------------------- hasCode:-1660511584
可以看到在新的SingleTaskActivity还没创建之前MainActivity就已经收到了回调并获取焦点然后马上又失去焦点。然后SingleTaskActivity才创建。
在5.0以后(包含)就不会出现这个情况了
日志如下:
MainActivity :onPause 方法-------------------- hasCode:56699745
SingleInstanceActivity :onCreate 方法-------------------------
SingleInstanceActivity :onCreate:SingleInstanceActivity hasCode:156403808 TaskId:249 TaskNum:2 TaskAffinity:com.hugo.aaaaaaaaaaa
SingleInstanceActivity :onStart 方法------------------ hasCode:156403808
SingleInstanceActivity :onResume 方法-------------------- hasCode:156403808
MainActivity :onSaveInstanceState 方法------------------ hasCode:56699745
MainActivity :onStop 方法------------------- hasCode:56699745
MainActivity :onRestart 方法------------------- hasCode:56699745
MainActivity :onStart 方法------------------ hasCode:56699745
MainActivity :onActivityResult 获取数据:null requestCode:10002
MainActivity :onResume 方法-------------------- hasCode:56699745
MainActivity :onPause 方法-------------------- hasCode:56699745
MainActivity :onStop 方法------------------- hasCode:56699745
MainActivity :onDestroy 方法------------------- hasCode:56699745
SingleInstanceActivity :onStop 方法------------------- hasCode:156403808
SingleInstanceActivity :onDestroy 方法------------------- hasCode:156403808
可以看到在5.0以后是可以正常返回的。==但是启动模式已经失去了做用==。SingleInstance启动模式下的Activity所在任务栈只能有唯一一个该Activity的实例,但是在日志中我们看到在这个任务栈中有2个实例。所以我们可以确定在Android5.0之后为了保证回调的功能,如果是startActivityForResult()启动的Activity,那么不管是设置的SingleTask还是SingleInstance都不会去创建新的任务栈,而是创建实例存入该任务栈中。所以在5.0之后没有出现那个一启动就回调的问题。
注意:如果你在开发关于这个的问题记得向下兼容。
这个例子的代码在这里