android Task相关

又看了一下谷歌文档关于 task 的部分,总结一下。

task 的数据结构是栈,它里面依次存放了为了完成某项工作而被启动的一系列activity, 这些 activity 的存放顺序就是他们被打开的顺序,最先打开的在最下面,最后打开的在最上面。 

当用户点击屏幕上的某个应用图标时,这个应用的 task 会被带到前台。如果这个应用的 task 不存在,就创建一个。新创建的时候,这个应用的 main activity 会作为这个新 task 的 root,也就是最下面的一个 activity。这说明 task 最初是在第一次点击应用的入口图标打开应用(一个应用可以有多个入口,多个图标) 的时候创建的。

task 是一个栈,它的操作只有 出栈 和 入栈(压栈)。当一个 activity A 被另一个 activity B 启动时,这个 activity A 会被压入到 activity B 所在的 task 中,成为处于栈顶的 activity。前台 task 的栈顶 activity 具有焦点。当在当前 activity 中按 back 键退出时,会将当前 activity 从它所在的栈中挤出,即是出栈。也就是说,被栈顶 activity 启动的 activity 才会入栈,点击 back 键退出的 activity 才会出栈。当使用 back 键将 task 中的 activity 全部出栈后,task 被销毁。

如果是按 home 键回到主屏幕,那么之前的 task 不会被销毁,而是进入后台。进入后台的 task 中依然保持着进入后台之前栈中的所有 activity,且对它们的状态进行了保存,以便恢复。当系统内存不足时,某些 activity 可能会被销毁。如果一个后台 activity 因为内存不足被销毁了,那么它之前所在的 task 中依然保留它的位置,在下一次 task 来到前台,并将它置于栈顶时,它会被重新启动。也就是说,它依然会按照顺序被打开,只是之前的状态不在了而已。

当一个 task 在后台待了比较长的一段时间,系统会清除掉这个 task 中除了 栈底activity 之外的所有 activity。

以上说的是系统默认的处理。我们也可以人为的管理 task。主要是通过 设置activity的启动模式 和 taskAffinity谷歌文档提示:尽管我们可以,但是对大部分应用来说,没有必要也不推荐我们自行管理task。


先说一下 taskAffinity。这个属性也是在 AndroidManifest.xml 中的 <activity> 标签下设置的,使用 android:taskAffinity=“” 来设置。taskAffinity 的名称用来标识 task, 可以自己定,但是中间至少要有一个 '.' 分隔符,也就是说这少是 “a.b”这种形式的。

taskAffinity 表明了这个 activity 更愿意被放入到哪个 task 里( affinity indicates which task an activity prefers to belong to )。默认情况下,在同一个 application 中的所有 activity 的 taskAffinity 都是在该 application 的 manifest 文件中被声明的包名。所以你要是想自己设置的话,新设置的名称一定不要使用包名。

taskAffinity 属性只在两种情况下会用到:

1)。当一个 activity 要以 singleTask 的形式被启动时,这个在后面讲到 singleTask 时细说。

2)。当一个 activity 将它的 allowTaskReparenting 属性设置为 true 时。

In this case, the activity can move from the task it starts to the task it has an affinity for, when that task comes to the foreground.


设置 activity 的启动模式有两种方法:1. 启动方在其发送的 intent 中添加 fiag; 2. 被启动方在其 AndroidManifest.xml 中的 <activity> 标签下设置 android:launchMode 属性。

如果以上两种方法都设置了了,1 压倒 2.


1. 设置 android:launchMode 属性

这个属性可以有四种选择。

1)。standard

就是上述的系统一般行为。这个是默认选项

这种情况下,一个 task 里面可以有多个 同一个 activity 的实例。大家可以做个测试,一个 activity 启动自己多次,会在这个 task 里面创建多个实例。每一个启动该 activity 的intent 都由 onCreate 来接收,以创建新实例。

2)。singleTop

设置为这个属性的时候,当一个 activity 被启动时,会先去判断当前 task 的 栈顶activity 是不是该 activity 的实例,也就是判断当前的 前台activity 是不是该 activity 的实例。如果是,当前传过来的要启动这个 activity 的 intent 会被传送给栈顶 activity 的 onNewIntent 方法,由它来处理;如果不是,根据这个 intent 创建新的实例,加入到 task 的栈顶。

也就是说,如果这个 activity 已经在栈顶了,就不会在创建新的实例,而是把 intent 传递给栈顶的 activity 实例的 onNewIntent 方法来处理。

3)。singleTask

当一个 activity 要以 singleTask 的形式被启动时,它会先去查找在当前存在的所有 task 中是否有 该activity 的实例,如果有,将 intent 发送给这个实例的 onNewIntent 方法,然后将该实例所在的task 带到前台带到前台是通过杀死位于其上方的activity来实现的;如果没有,它会去寻找当前是否存在和它的 taskAffinity 属性标识一致的 task,如果有,它启动后,会被加入到那个 task 中,并将该 task 带到前台;如果没有,它启动后,会被放到一个新的 task 中。

4)。singleInstance

这个基本上和 singleTask 一样,只有一样,那就是这样设置的 activity 被启动后,它所在的 task 里面永远只有它这么一个 actvity 实例。它和启动它的 activity 一定不在同一个 task 里,它启动的 activity 也一定不在它的 task 里。


2. 启动方通过在 intent 中设置 flag 来设置启动模式

这样的 filag 有三种。

1)。FLAG_ACTIVITY_NEW_TASK

和上面讲的在 manifest 中设置 singleTask 一样。

2)。FLAG_ACTIVITY_SINGLE_TOP

和上面讲的在 manifest 中设置 singleTop 一样。

3)。FLAG_ACTIVITY_CLEAR_TOP

如果启动方在 intent 中设置了这个 flag,那么被启动的 activity 会首先查找在 当前task 中有没有它的实例,如果有,就把在栈中位于这个实例之上的其他 activity 实例都销毁掉,然后把 Intent 传递给这个实例的 onNewIntent,并将该实例带到前台。

这个 flag 通常和 FLAG_ACTIVITY_NEW_TASK 一起使用。



上文提到,如果一个 task 在后台待了比较长的时候,那么系统会销毁掉这个 task 中除了 root 之外的其他 activity。这个行为也可以被设置,同样是在 manifest 文件中。有以下三种属性可以设置:

1)。alwaysRetainTaskState

如果在 task 中 root activity 的 <activity> 标签里将这个属性设置为 true,那么不管在后台待多长时间,这个 task 中的 activity 都不会被销毁。

2)。clearTaskOnLaunch

如果在 task 中 root activity 的 <activity> 标签里将这个属性设置为 true,那么每次启动这个 task,不管之间间隔的时间有多长或者多短,都会将 task 中的 activity 都销毁,然后从 main activity 重新打开这个task。它和上一个属性正好相反。

3)。finishOnTaskLaunch

这个属性是为单个的 activity 设置的,如果在某个 activity 的 <activity> 标签里将这个属性设置为 true,那么当用户离开它所属的 task,然后又返回后,这个 activity 将不再显示。也就是每次 task 重新打开的时候,这个 activity 都会被销毁。


前文提到,在屏幕上点击一个 application 的图标通常是第一次打开一个 task 的方法。我们可以认为,提供这个图标的 activity 是这个 task 的入口。那么什么样的 activity 可以提供图标呢?那就是以下这样的。

<activity
            android:icon="@drawable/ic_launcher"
            android:name="com.example.taskstest.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


在 intent-filter 中设置了 main action 和 Launcher category,就可以作为一个 task 的入口了。

有时在一个 application 中要提供多个 task 入口(如源码中的 Contacts),就可以多设置几个这样的 activity,并给他们每个都提供一个不一样的图标。

谷歌提示:singleTask 和 singleInstance 应该只是给这样的可以作为 task 入口的activity 设置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Debug Bridge (ADB) 是一种用于在电脑和手机之间进行通信和控制的工具。它的运行原理是通过 PC 端的 adb server 与手机端的守护进程 adbd 建立连接,然后 PC 端的 adb client 通过 adb server 转发命令,adbd 接收命令后解析运行。 有些需要 root 权限才能执行的命令无法直接使用 adb 执行。为了解决这个问题,有两种方法可以执行高权限命令。一种是通过在 adb shell 中输入 su 命令来切换至 root 权限,另一种是让 adbd 以 root 权限执行。可以通过执行 adb root 命令来让 adbd 以 root 权限执行高权限命令。执行成功后,adb shell 的命令行提示符应该会变成 #。 然而,部分手机或高版本的手机无法通过 adb root 命令让 adbd 以 root 权限执行,会提示 "adbd cannot run as root in production builds"。如果想要将 adbd 回复为非 root 权限,可以使用 adb unroot 命令。此命令会将 adbd 还原为非 root 权限。 除了以上命令,还有一些其他的 adb 命令可以使用。例如,可以通过 adb kill-server 命令停止 adb server,通过 adb version 命令查看 ADB 版本等。同时,还可以使用 adb -P <port> start-server 命令来指定 adb server 的网络端口。 总结来说,android adb 是一种用于在电脑和手机之间进行通信和控制的工具,可以通过 adb server 与 adbd 建立连接并执行命令。为了执行高权限命令,可以使用 adb root 命令,但部分手机可能不支持。此外,还有一些其他的 adb 命令可以用来停止 adb server、查看 ADB 版本等。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Android adb说明与详解](https://blog.csdn.net/h_bpdwn/article/details/131718659)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值