Android allowTaskReparenting clearTaskOnLaunch alwaysRetainTaskState

android:allowTaskReparenting

翻译过来的一下是允许重新找父母大笑(允许迁移任务栈),如果一个Activity设置了这个属性,其他应用启动这个activity的时候分两种情况处理:

1.这个activity对应的进程已经启动了:则这个activity直接附属到自己所对应的进程的应用栈上

2.这个activity对应的进程没有启动:则这个activity先直接附属到启动它的应用的应用栈上,当activity对应的进程启动后,则会主动迁移到activity对应的进程。

有一个比喻非常之形象:

你捡到一条狗,在家里喂养几天觉得不错,当自己家的了;但是突然有一天他的主人找上门来了,小狗还是乖乖和主人走了。。。大哭大哭

这条狗就是带有allowTaskReparenting属性的activity 


demo1(com.cn.demo1)有两个activity: MainActivity,AllowTaskReparentingActivity, AllowTaskReparentingActivity设置了android:allowTaskReparenting="true"属性

demo2(com.cn.demo2)有一个activity:MainActivity

安装demo1demo2之后,先启动demo2,在demo2中demo1中的AllowTaskReparentingActivity,使用dumpsys activity activities查看堆栈情况:

    Running activities (most recent first):

      TaskRecord{4497c288 #566 A=com.cn.demo2 U=0 sz=2}

        Run #2: ActivityRecord{44664828 u0 com.cn.demo1/.AllowTaskReparentingActivity t566}

        Run #1: ActivityRecord{4497bf70 u0 com.cn.demo2/.MainActivity t566}

      TaskRecord{4321d2d0 #83 A=com.android.packageinstaller U=0 sz=1}

        Run #0: ActivityRecord{4409df10 u0 com.android.packageinstaller/.PackageInstallerActivity t83}
任务栈com.cn.demo2有两个Activity,一个是demo2的MainActivity,一个是demo1的AllowTaskReparentingActivity, AllowTaskReparentingActivity在上,MainActivity在下

按Home退出到后台,堆栈状态不变,再点击demo2图标打开demo2,查看堆栈情况

    Running activities (most recent first):

      TaskRecord{4497c288 #566 A=com.cn.demo2 U=0 sz=1}

        Run #2: ActivityRecord{4497bf70 u0 com.cn.demo2/.MainActivity t566}

      TaskRecord{43aa4278 #564 A=com.cn.demo1 U=0 sz=2}

        Run #1: ActivityRecord{44664828 u0 com.cn.demo1/.AllowTaskReparentingActivity t564}

      TaskRecord{4321d2d0 #83 A=com.android.packageinstaller U=0 sz=1}

        Run #0: ActivityRecord{4409df10 u0 com.android.packageinstaller/.PackageInstallerActivity t83}

OK,重新点击图标的时候com.cn.demo2/.MainActivity和com.cn.demo1/.AllowTaskReparentingActivity已经分离开了,这就是 android:allowTaskReparenting=true起到的作用,如果为false,任务栈的状态时不会变(分离)的。

如果用demo2启动com.cn.demo1/.AllowTaskReparentingActivity,然后Home退出到桌面,然后再点击demo1图标看一下堆栈状态

    Running activities (most recent first):

      TaskRecord{442f3588 #585 A=com.cn.demo1 U=0 sz=2}

        Run #2: ActivityRecord{43d9f308 u0 com.cn.demo1/.AllowTaskReparentingActivity t585}

      TaskRecord{448abf70 #584 A=com.cn.demo2 U=0 sz=1}

        Run #1: ActivityRecord{43d42230 u0 com.cn.demo2/.MainActivity t584}

      TaskRecord{4321d2d0 #83 A=com.android.packageinstaller U=0 sz=1}

        Run #0: ActivityRecord{4409df10 u0 com.android.packageinstaller/.PackageInstallerActivity t83}
效果是一样的,我们产看一下编号#585堆栈的activity情况如下:

  Recent tasks:

  * Recent #0: TaskRecord{442f3588 #585 A=com.cn.demo1 U=0 sz=2}

    numActivities=2 rootWasReset=true userId=0 mTaskType=0 numFullscreen=2 mOnTopOfHome=true

    affinity=com.cn.demo1

    intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.cn.demo1/.MainActivity}

    realActivity=com.cn.demo1/.MainActivity

    Activities=[ActivityRecord{43e2c298 u0 com.cn.demo1/.MainActivity t585}, ActivityRecord{43d9f308 u0 com.cn.demo1/.AllowTaskReparentingActivity t585}]

    askedCompatMode=false

    lastThumbnail=null lastDescription=null

    lastActiveTime=1704769727 (inactive for 6s)

变量Activities里面有两个activity:Activities=[ActivityRecord{43e2c298 u0 com.cn.demo1/.MainActivity t585}, ActivityRecord{43d9f308 u0 com.cn.demo1/.AllowTaskReparentingActivity t585}]其中MainActivity在下,AllowTaskReparentingActivity在上,可以猜测是demo1先启动的MainActivity,再将AllowTaskReparentingActivity从栈com.cn.demo2迁移到栈com.cn.demo1上。


android:allowTaskReparenting在提供页面给第三方调用的时候能够被用到。

Demo下载


android:clearTaskOnLaunch

这个属性用来标记是否从task清除除根Activity之外的所有的Activity,“true”表示清除,“false”表示不清除,默认为“false”。同样,这个属性也只对根Activity起作用,其他的Activity都会被忽略。
如果设置了这个属性为“true”,每次用户重新启动这个应用时,都只会看到根Activity,task中的其他Activity都会被清除出栈。如果我们的应用中引用到了其他应用的Activity,这些Activity设置了allowTaskReparenting属性为“true”,则它们会被重新宿主到有共同affinity的task中。

启动A后,再点击按钮启动B,点击home键,返回到home screen 。(A、B属于同一个栈)
a.长按home键,在recent中点击应用图标,显示B界面。
b.再点击应用图标,显示A界面

根据这一个表现,则说明从launch点击图标进入应用和长按Home键从最近列表进入应用是有区别的,区别如下:

1.点击Launcher里面的图标,本质上就是调用的startActivity,action是android.intent.action.MAIN,category是android.intent.category.LAUNCHER,flag是FLAG_ACTIVITY_RESET_TASK_IF_NEEDED & FLAG_ACTIVITY_NEW_TASK,component是你的A。

2.从RecentActivity进入,源码里面对flag做了这种处理:intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) | Intent.FLAG_ACTIVITY_NEW_TASK);去掉了flag里面FLAG_ACTIVITY_RESET_TASK_IF_NEEDED那一位标志。

区别就在于FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,一旦用户设置了FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,那么就会执行resetTaskIfNeeded来清理task,很明显这种情况下从Home进入的时候清理了Task,而从最近列表进入则resume顶部的activity。


android:alwaysRetainTaskState

如果用户在一定时间内不再访问Task,比如说30分钟,那么系统有可能会清楚Task中的状态(只保留root activity)。设置此属性为"true"可以避免这种情况


android:finishOnTaskLaunch

当Task再次被启动是,设置android:finishOnTaskLaunch为true,该Activity就销毁,我还不知道怎么让Task再次启动





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值