Acitvity Task详解

可以使用hierarchyviewer 查看Acitvity 、Task的顺序与结构。

Activity一共有以下四种launchMode:

1.standard

2.singleTop

3.singleTask

4.singleInstance

我们可以在AndroidManifest.xml配置<activity>的android:launchMode属性为以上四种之一即可。

他们之间得区别与用法我不多讲,网上有很多。

假象如下情景:

用户从Launcher启动短信列表界面(ConversationList),点击编辑按钮进入短信编辑界面(ConversationEdit)

Launcher启动ConversationList的时候 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)


                      |                             |   ConversationEdit  |

                      |  Launcher.java      |   ConversationList    |

                      ————————————————————  

                      Task1                            Task2                   

当用户从ConversationEdit点击Home回到桌面,再次点击短信快捷方式的时候,会将Task2整体移到前台。

[疑惑:

为什么锁屏解锁的时候中通过FLAG_ACTIVITY_NEW_TASK 启动CameraActivity就不会

将用户把Launcher之前已经启动的CameraActivity所在的Task移到前台?而是

新建一个Task装载新的CameraActivity实例]

真相:同一个Context中,启动多次短信 Intent 那么会将Task2整体移到前台,

          如果是不同的Context,那么会启动新Task(前提是短信的 android:launchMode 是 standard

     


但是又发现问题:下面这个现象完全否定了我的上面的“真相”

                   Intent intent = new Intent("android.media.action.STILL_IMAGE_CAMERA");
                   intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                   startActivity(intent);

 我自己写了一个Demo效仿 LockScreen.java 启动Camera,按理说他们Demo和LockScreen是在不同的Context

 但是我神奇的发现,他们尽然会使用同一个Camera实例?


好吧,不得不推翻上面得真相了!

真相2:

解答上面的[疑惑]:因为锁屏和Launcher启动Camera得Intent不相同!

锁屏:Intent intent = new Intent("android.media.action.STILL_IMAGE_CAMERA");

Launcher:

//Intent intent =  new Intent();  
//                ComponentName comp = new ComponentName(  
 //                       "com.android.camera",  
  //                      "com.android.camera.Camera");  
   //             intent.setComponent(comp);

如果锁屏和Launcher启动Camera的Intent的Action相同,那么如果他们都是以FLAG_ACTIVITY_NEW_TASK的方式启动的

那么他们会共用一个Task(包含CameraAcitvity)以Launcher中打开一个app的activity直接进入之前打开的Task 而不是新打开一个activity.





 PhoneWindowManager.java:startDockOrHome();  

  1.       mHomeIntent =  new Intent(Intent.ACTION_MAIN, null);  
  2.       mHomeIntent.addCategory(Intent.CATEGORY_HOME);  
  3.       mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK  
  4.       | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);  
这段代码是在init()方法中,对mHomeIntent的初始化,这个Intent就是跳转到Launcher程序中的配置了 <category android:name="android.intent.category.HOME" />这个属性的Launcher Activity,另外我们还看到两个flag
[java]
  1. FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_RESET_TASK_IF_NEEDED  

     FLAG_ACTIVITY_NEW_TASK保证了我们回到之前Launcher所在的栈,FLAG_ACTIVITY_RESET_TASK_IF_NEEDED  是设置清理栈标志,保证清除掉该栈除Launcher以外其他activity(在Launcher清单文件中我们还看到android:clearTaskOnLaunch="true"这个属性,后面会描述),这样我们的Launcher当然会在自己单独的Task中,而且android:launchMode="singleTask"这个属性保证不会启动一个新的Launcher。

       通过Launcher启动的其他Activity不会跑到Launcher所在的Task中(后面的文章会提到Launcher启动activity的过程)。所以按Home键是打开了Launcher这个activity并且保证他在自己单独的Task中,其他的activity进入stop状态。


疑惑三:android:clearTaskOnLaunch   FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

我把Launcher启动app时候的FLAG_ACTIVITY_NEW_TASK去掉,那么他和短信界面应该在一个Task里面了吧?但是我按home返回桌面,第二次再次进入

短信的时候,它还在编辑界面,android:clearTaskOnLaunch并没有起作用?

配置了android:clearTaskOnLaunch = true的Acitvity重启启动start的时候 会清除当前栈 除Launcher以外的Actvity ,

================================================

默认同一个应用里面的Acitvity是具有相同亲属性的。

默认情况下,一个被激活的新activity会和负责激活它的那个activity组件存在于同一个任务栈中。但是若负责激活的Intent对象包含了FLAG_ACTIVITY_NEW_TASK标志,则系统会为存放那个即被激活的新activity寻找一个新的任务栈。此时,若已经存在了相同亲属关系的任务栈,则系统会直接将这个即被激活的新activity放入到这个任务栈中;否则系统会开始一个新的任务栈。 

你可能感兴趣的:(Acitvity Task详解)