“singleTask”模式 切换到新的栈中[通俗易懂]

“singleTask”模式 切换到新的栈中[通俗易懂]本文截取了网络资源的结论部分对singletask启动模式做笔记记录。虽然SubActivity的launchMode被设置为”singleTask”模式,但是它并不像官方文档描述的一样:Thesystemcreatesanewtaskandinstantiatestheactivityattherootofthenewtask,而是在跟它有相同

大家好,欢迎来到IT知识分享网。

本文截取了网络资源的结论部分 对singletask 启动模式做笔记记录。

虽然SubActivity的launchMode被设置为”singleTask”模式,但是它并不像官方文档描述的一样:The system creates a new task and instantiates the activity at the root of the new task,而是在跟它有相同taskAffinity的任务中启动,并且位于这个任务的堆栈顶端,于是,前面那个图中,就会出现一个带着”singleTask”标签的箭头指向一个任务堆栈顶端的Activity Y了。

        那么,我们有没有办法让一个”singleTask”的Activity在新的任务中启动呢?答案是肯定的。从上面的代码分析中,只要我们能够进入函数startActivityUncheckedLocked的这个if语句中:

  1.  if (r.resultTo == null && !addingToTask  
  2.        && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {  
  3. // todo: should do better management of integers.  
  4.        mService.mCurTask++;  
  5.        if (mService.mCurTask <= 0) {  
  6.             mService.mCurTask = 1;  
  7.        }  
  8.        r.task = new TaskRecord(mService.mCurTask, r.info, intent,  
  9.                   (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);  
  10.        if (DEBUG_TASKS) Slog.v(TAG, “Starting new activity “ + r  
  11.                   + ” in new task “ + r.task);  
  12.         newTask = true;  
  13.         if (mMainStack) {  
  14.               mService.addRecentTaskLocked(r.task);  
  15.         }  
  16.  }  

        那么,这个即将要启动的Activity就会在新的任务中启动了。进入这个if语句需要满足三个条件,r.resultTo为null,launchFlags的Intent.FLAG_ACTIVITY_NEW_TASK位为1,并且addingToTask值为false。从上面的分析中可以看到,当即将要启动的Activity的launchMode为”singleTask”,并且调用startActivity时不要求返回要启动的Activity的执行结果时,前面两个条件可以满足,要满足第三个条件,只要当前系统不存在affinity属性值等于即将要启动的Activity的taskAffinity属性值的任务就可以了。

        我们可以稍微修改一下上面的AndroidManifest.xml配置文件来做一下这个实验:

  1. <?xml version=“1.0” encoding=“utf-8”?>    
  2. <manifest xmlns:android=“http://schemas.android.com/apk/res/android”    
  3.     package=“shy.luo.task”    
  4.     android:versionCode=“1”    
  5.     android:versionName=“1.0”>    
  6.     <application android:icon=“@drawable/icon” android:label=“@string/app_name”>    
  7.         <activity android:name=“.MainActivity”    
  8.                   android:label=“@string/app_name”  
  9.                   android:taskAffinity=“shy.luo.task.main.activity”>    
  10.             <intent-filter>    
  11.                 <action android:name=“android.intent.action.MAIN” />    
  12.                 <category android:name=“android.intent.category.LAUNCHER” />    
  13.             </intent-filter>    
  14.         </activity>    
  15.         <activity android:name=“.SubActivity”    
  16.                   android:label=“@string/sub_activity”  
  17.                   android:launchMode=“singleTask”  
  18.                   android:taskAffinity=“shy.luo.task.sub.activity”>    
  19.             <intent-filter>    
  20.                 <action android:name=“shy.luo.task.subactivity”/>    
  21.                 <category android:name=“android.intent.category.DEFAULT”/>    
  22.             </intent-filter>    
  23.         </activity>    
  24.     </application>    
  25. </manifest>    

        注意,这里我们设置MainActivity的taskAffinity属性值为”shy.luo.task.main.activity”,设置SubActivity的taskAffinity属性值为”shy.luo.task.sub.activity”。重新编译一下程序,在模拟器上把这个应用程序再次跑起来,用“adb shell dumpsys activity”命令再来查看一下系统运行的的任务,就会看到:

  1. Running activities (most recent first):  
  2.     TaskRecord{4069c020 #4 A shy.luo.task.sub.activity}  
  3.       Run #2: HistoryRecord{40725040 shy.luo.task/.SubActivity}  
  4.     TaskRecord{40695220 #3 A shy.luo.task.main.activity}  
  5.       Run #1: HistoryRecord{406b26b8 shy.luo.task/.MainActivity}  
  6.     TaskRecord{40599c90 #2 A com.android.launcher}  
  7.       Run #0: HistoryRecord{40646628 com.android.launcher/com.android.launcher2.Launcher}  

        这里就可以看到,SubActivity和MainActivity就分别运行在不同的任务中了。

        至此,我们总结一下,设置了”singleTask”启动模式的Activity的特点:

        1. 设置了”singleTask”启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性值taskAffinity的任务存在;如果存在这样的任务,它就会在这个任务中启动,否则就会在新任务中启动。因此,如果我们想要设置了”singleTask”启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。

        2. 如果设置了”singleTask”启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity实例会位于任务的堆栈顶端中。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/24646.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信