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。

case 1:在AndroidManifest.xml中定义的属性为:

        <activity
            android:name="com.coder80.appother.MainActivity"
            android:label="AppOther MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
       ... .... .... ....
        <activity
            android:name="com.coder80.appother.OtherActivity"
            android:label="AppOther OtherActivity"
            >
        </activity>

app运行效果如下:

    

在OtherActivity界面,多次点击“Start AppOther OtherActivity in AppOther”按钮,会启动多个Activity Instance,由于两个Activity拥有共同的taskAffinity,将处于同一个task里面。

case 2:在AndroidManifest.xml中定义的属性为:

<activity
    android:name="com.coder80.appother.MainActivity"
    android:label="AppOther MainActivity" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity
    android:name="com.coder80.appother.OtherActivity"
    android:label="AppOther OtherActivity"
    android:taskAffinity="com.xxxx"
    >
</activity>

app运行效果如下:

 

在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的<activity>元素没有设定此属性,则为默认方式。继续用demo进行演示,进行深入浅出的分析。

应用TaskAffinity的MainActivity中,点击按钮,进入应用AppOther的OtherActivity,其对应AndroidManifest.xml中定义的属性如下:

TaskAffinity的AndroidManifest.xml

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.coder80.taskaffinity.MainActivity"
            android:label="TaskAffinity MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

AppOther的AndroidManifest.xml

        <activity
            android:name="com.coder80.appother.OtherActivity"
            android:label="AppOther OtherActivity"
            >
            <intent-filter>
                <action android:name="android.intent.action.AppOther_OTHER_ACTIVITY" />
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

首先运行TaskAffinity应用,启动界面如下:

  点击“Start AppOther OtherActivity”按钮,执行如下的代码:

				Intent intent = new Intent("android.intent.action.AppOther_OTHER_ACTIVITY");
				startActivity(intent); 

将启动AppOther中的OtherActivity界面,效果如下:

  两个Activity的task id 一致,表明是在同一个task里面。此时,按下“Home”键,显示主屏,之后再菜单中点击TaskAffinity应用图标,启动之后,界面如下:

 
依旧显示的是AppOther应用的OtherActivity界面。

由此demo,了解到,不同应用的Activity,可以处于同一个task里面,并且使用默认的allowTaskReparenting属性,其task在由后台转入前台时,不会从task remove。

示例将做小小改动,修改AppOther中OtherActivity的属性,将allowTaskReparenting置为true,其他的代码,不做任何修改,AndroidManifest.xml如下:

        <activity
            android:name="com.coder80.appother.OtherActivity"
            android:label="AppOther OtherActivity"
            android:allowTaskReparenting="true"
            >
            <intent-filter>
                <action android:name="android.intent.action.AppOther_OTHER_ACTIVITY" />
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

运行后,效果图如下:

TaskAffinity应用图                  点击按钮,启动OtherActivity图  按下home键后,再次TaskAffinity图

    

从上述示例,可以得知,android:allowTaskReparenting="true",对于Activity的作用了。

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

时间: 2024-08-14 21:14:26

Android launchMode 笔记---taskAffinity属性和Intent标记体会的相关文章

android launchMode加载模式和intent flag

ApplicationTask和Process的区别与联系 Application task process 四种加载模式 standard模式 singleTop模式 singleTask模式 singleInstance模式 SingleTask和SingleInstance区别 实例 startActivityForResult如果被启动activity加载模式为SingleTask和SingleInstance 使用Intent标志 FLAG_ACTIVITY_NEW_TASK FLAG

Android学习笔记(八) Intent

在一开始学习Android的过程中,对于Intent并没有太深入的理解,以为Intent只是作为一个传数据的中间对象,但是随着学习内容的增多,发现Intent的机制实际上贯穿于整个Android的过程: 1.Intent启动:Intent的传输数据只是作为其中一个重要的功能而存在,但是其更重要的作用在于启动/调用的机制,Android如何启动/调用一个应用.组件,首先需要的是一个定位的过程,需要启动哪个组件?指定的某个组件.或者是某个类型的组件,通过抽象成Intent进行统一的调用,只要对Int

Android学习笔记(十一) Intent

一.Intent对象的基本概念 -Intent是Android应用程序组件之一 -Intent对象在Android系统当中表示一种意图 -Intent当中最重要的内容是action与data 二.Intent对象的基本使用方法 Intent intent = new Intent(); intent.setClass(MainActivity.this,OtherActivity.class); //此处放入putExtra语句用于存放数据 startActivity(intent); 三.使用

Android 学习笔记(10)—— Intent 基本运用

作者:夏至 欢迎转载,也请保留这段申明,谢谢 最近太忙了,都没什么时间来整理,前9个上传之后格式不对,都没好好整理,以后会抽空整理. Android的通信桥梁 -- Intent . 使用一个activity实在是太简单了,布局上也有限,那我们能不能像我们真机上的一样,一点就跳到另一个界面去了.这里我们就使用Intent,在活动中穿梭.至于为什么学着UI组件,突然跑到这个家伙来,那当然是为下一节做准备啦.除了活动,它还可以是服务或者广播.启动可以下列方法: startActivity(Inten

Android学习笔记三:用Intent串联activity

一:Intent Intent可以理解为 意图. 我们可以通过创建intent实例来定义一个跳转意图,意图包括:要跳转到哪个页面.需要传递什么数据. 然后通过startActivity(intent)来启动跳转. 有两种方式定义Intent:显式Intent.隐式Intent. 二:显式Intent 1)我们可以在actvity的java文件中,通过代码显示定义Intent,参数为:从哪个页面,跳转到哪个页面. Intent intent = new Intent(FirstActivity.t

android当中taskAffinity属性与launchMode相关

一.本文尝试解释以下问题 1.  Activity被启动之后放在哪个任务栈当中?与哪些因素有关? 2.  Activity的四种启动模式对Activity的启动有哪些影响? 3.  在Activity中使用startActivityForResult(intent, REQUESTCODE);和onActivityResult() 是否与被启动的Activity的launchMode有关?如果有关,有什么关系? 二.Activity被启动之后放在哪个任务栈当中?与哪些因素有关? 1.基本论断:A

Android总结篇系列:Activity Intent Flags及Task相关属性

同上文一样,本文主要引用自网上现有博文,并加上一些自己的理解,在此感谢原作者. 原文地址: http://blog.csdn.net/liuhe688/article/details/6761337 -------------------------------------------------------------------------- 今天我们来讲一下Activity的task相关内容. 上次我们讲到Activity的四种启动模式的时候,已经了解到一些关于task的技术,今天我再向大

Activity之taskAffinity属性、allowTaskReparenting属性和Android退出整个应用解决方案

allowTaskReparenting属性 属性: android:allowTaskReparenting 除了launchMode可以用来调配Task,的另一属性taskAffinity,也是常常被使用.taskAffinity,是一种物以类聚的思想,它倾向于将taskAffinity属性相同的Activity,扔进同一个Task中.不过,它的约束力,较之launchMode而言,弱了许多.只有当中的allowTaskReparen ting设置为true,抑或是调用方将Intent的fl

Android学习笔记之mainfest文件中android属性

Android学习笔记之mainfest文件中android属性 - Impossible is nothing - 博客频道 - CSDN.NET 以前的零散笔记, 共享一下, 有错误的地方还请指正. android:allowTaskReparenting 是否允许activity更换从属的任务,比如从短信息任务 切换到浏览器任务.---------------------------------------------------------------------------------