Android launchMode 笔记---taskAffinity属性和Intent标记体会

       launchmode的四种模式,不需要细说:standard、singleTop、singleTask、singleInstance。
    此博客关注的是,关于Activity中关于 Affinity(亲和力)&Intent标记的东西,即使是Android老鸟,也不一定将其中的细节理解透彻。
使用Intent启动一个Activity,有如下标记: 
1、FLAG_ACTIVITY_NEW_TASK
2、FLAG_ACTIVITY_CLEAR_TOP
3、FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
4、FLAG_ACTIVITY_SINGLE_TOP 
使用最多的,当然是FLAG_ACTIVITY_NEW_TASK。
主要的Activity属性有:
1、taskAffinity
2、launchMode
3、allowTaskReparenting
4、clearTaskOnLaunch
5、alwaysRetainTaskState
6、finishOnTaskLaunch 
     当Affinity与LaunchMode结合起来使用,就比较让人蛋疼的事情了。在实际项目中,灵活使用各种属性,可以让程序运行流畅,界面直接的导航跳转流畅,用户体验良好。反之,则让人摸不着头脑,让人蛋疼。绝知此事须躬行的道理,才油然而生。
关于上述的各种属性,可以参看Google文档,Tasks and Back Stack ,文档中将各种情况分析得较为全面,网上的资料,均是翻译其内容。
FLAG_ACTIVITY_NEW_TASK 讲解
case 1:当Intent对象包含这个标记时,系统会寻找或创建一个新的task来放置目标Activity,寻找时依据目标Activity的taskAffinity属性进行匹配,如果找到一个task的taskAffinity与之相同,就将目标Activity压入此task中。
case 2:如果查找无果,则创建一个新的task,并将该task的taskAffinity设置为目标Activity的taskActivity,将目标Activity放置于此task。
上面的两个case,可以简单的理解为:
FLAG_ACTIVITY_NEW_TASK标记,不一定会启动一个新的栈,其策略是:先查找有没有和这个Activity的affinity相同的task栈,如果有,则直接在这个task栈里启动,没有才创建一个新的task栈。
case 3:如果同一个应用中Activity的taskAffinity都使用默认值或都设置相同值时,应用内的Activity之间的跳转使用这个标记是没有意义的,因为当前应用task就是目标Activity最好的宿主。
为了更好的说明其中的扯淡关系,使用案例进行说明上述的case 1、case 2、case 3
一个简单的app中,MainActivity点击按钮启动一个新的Activity。
Android launchMode 笔记---taskAffinity属性和Intent标记体会_第1张图片  
case 1:在AndroidManifest.xml中定义的属性为:

        
            
                
                
            
        
       ... .... .... .... 
        
        
app运行效果如下:
Android launchMode 笔记---taskAffinity属性和Intent标记体会_第2张图片     Android launchMode 笔记---taskAffinity属性和Intent标记体会_第3张图片
在OtherActivity界面,多次点击“Start AppOther OtherActivity in AppOther”按钮,会启动多个Activity Instance,由于两个Activity拥有共同的taskAffinity,将处于同一个task里面。
case 2:在AndroidManifest.xml中定义的属性为:

    
        
        
    


app运行效果如下:
Android launchMode 笔记---taskAffinity属性和Intent标记体会_第4张图片  Android launchMode 笔记---taskAffinity属性和Intent标记体会_第5张图片
在OtherActivity界面,点击“Start AppOther OtherActivity in AppOther”按钮,创建新的Activity Instance,由于两个Activity拥有的taskAffinity不同,新的instant将处于另外的task里面,其task id 为23.
PS:此处多次点击点击“Start AppOther OtherActivity in AppOther”按钮,不会产生新的Activity Instance
           在case 2中,当界面停留在OtherActivity时,此时按Home键,让app进入后台运行,再次启动app,将直接显示MainActivity界面,而不是OtherActivity界面。主要原因是,该app的启动时,系统将寻找root Activity所处的那个task,而该app的root activity为MainActivity,所以显示MainActivity界面。
case 3:在AndroidManifest.xml中定义的属性为与case 1一致。
     此时Activity之间的导航,与普通的跳转一致,task的创建与否,直接根据launchMode来确定。
allowTaskReparenting讲解
      这个属性用来标记一个Activity实例在当前应用退居后台后,是否能从启动它的那个task移动到有共同affinity的task,“true”表示可以移动,“false”表示它必须呆在当前应用的task中,默认值为false。
      如果一个Activity的元素没有设定此属性,则为默认方式。继续用demo进行演示,进行深入浅出的分析。
      应用TaskAffinity的MainActivity中,点击按钮,进入应用AppOtherOtherActivity,其对应AndroidManifest.xml中定义的属性如下:
      TaskAffinityAndroidManifest.xml
    
        
            
                
                
            
        

AppOther的AndroidManifest.xml
        
            
                
                
            
        
    首先运行 TaskAffinity应用,启动界面如下:
Android launchMode 笔记---taskAffinity属性和Intent标记体会_第6张图片  点击“Start AppOther OtherActivity”按钮,执行如下的代码:
				Intent intent = new Intent("android.intent.action.AppOther_OTHER_ACTIVITY");  
				startActivity(intent); 
将启动 AppOther中的 OtherActivity界面,效果如下:
Android launchMode 笔记---taskAffinity属性和Intent标记体会_第7张图片  两个Activity的task id 一致,表明是在同一个task里面。此时,按下“Home”键,显示主屏,之后再菜单中点击 TaskAffinity应用图标,启动之后,界面如下:
Android launchMode 笔记---taskAffinity属性和Intent标记体会_第8张图片  依旧显示的是 AppOther应用的OtherActivity界面。
    由此demo,了解到,不同应用的Activity,可以处于同一个task里面,并且使用默认的allowTaskReparenting属性,其task在由后台转入前台时,不会从task remove。
    示例将做小小改动,修改AppOther中OtherActivity的属性,allowTaskReparenting置为true,其他的代码,不做任何修改,AndroidManifest.xml如下:
        
            
                
                
            
        
运行后,效果图如下:
   TaskAffinity应用图                  点击按钮,启动OtherActivity  按下home键后,再次TaskAffinity
Android launchMode 笔记---taskAffinity属性和Intent标记体会_第9张图片  Android launchMode 笔记---taskAffinity属性和Intent标记体会_第10张图片  Android launchMode 笔记---taskAffinity属性和Intent标记体会_第11张图片
 从上述示例,可以得知,android:allowTaskReparenting="true",对于Activity的作用了。

你可能感兴趣的:(Android基础知识讲解)