Android 启动优化- AnchorTask 开源了
Posted gdutxiaoxu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 启动优化- AnchorTask 开源了相关的知识,希望对你有一定的参考价值。
前两篇博客介绍了 android 启动优化多线程异步加载依赖问题的解决方案 - 有向无环图,以及如何实现有它。今天,让我们一起来看一下,在 Android 实战中,怎么实现。
Android 启动优化(二) - 拓扑排序的原理以及解题思路
简介
Android 启动优化,大家第一时间可能会想到异步加载。将耗时任务放到子线程加载,等到所有加载任务加载完成之后,再进入首页。
多线程异步加载方案确实是 ok 的。但如果遇到前后依赖的关系呢。比如任务2 依赖于任务 1,这时候要怎么解决呢。
这时候就可以使用 AnchorTask 解决,它的实现原理是构建一个有向无环图,拓扑排序之后,如果任务 B 依赖任务 A,那么 A 一定排在任务 B 之后。
基本使用
第一步:在 moulde build.gradle 配置远程依赖
1implementation 'com.xj.android:anchortask:0.1.0'
最新的版本号可以看这里 lastedt version
第二步:自定义 AnchorTaskB,继承 AnchorTask,重写相应的方法
1class AnchorTaskB : AnchorTask()
2 override fun isRunOnMainThread(): Boolean
3 return false
4
5
6 override fun run()
7 val start = System.currentTimeMillis()
8 try
9 // 在这里进行操作,这里通过睡眠模拟耗时操作
10 Thread.sleep(300)
11 catch (e: Exception)
12
13 com.xj.anchortask.library.log.LogUtils.i(
14 TAG, "AnchorTaskOne: " + (System.currentTimeMillis() - start)
15 )
16
17
18 // 返回依赖的任务,这里是通过 class name 去找到对应的 task
19 override fun getDependsTaskList(): List<Class<out AnchorTask>>?
20 return ArrayList<Class<out AnchorTask>>().apply
21 add(AnchorTaskA::class.java)
22
23
24
25
如果任务 C 依赖任务 B,任务 A,可以这样写
1class AnchorTaskC : AnchorTask()
2
3 override fun getDependsTaskList(): List<Class<out AnchorTask>>?
4 return ArrayList<Class<out AnchorTask>>().apply
5 add(AnchorTaskA::class.java)
6 add(AnchorTaskB::class.java)
7
8
9
10
最后,通过 AnchorTaskDispatcher.instance .addTask(AnchorTaskFive())
添加任务,并调用 start() 方法启动, await() 方法表示阻塞等待所有任务执行完毕。
1AnchorTaskDispatcher.instance.setContext(this).setLogLevel(LogUtils.LogLevel.DEBUG).setTimeOutMillion(1000L).
2 .addTask(AnchorTaskZero())
3 .addTask(AnchorTaskOne())
4 .addTask(AnchorTaskTwo())
5 .addTask(AnchorTaskThree())
6 .addTask(AnchorTaskFour())
7 .addTask(AnchorTaskFive())
8 .start()
9 .await()
AnchorTaskDispatcher 介绍
AnchorTaskDispatcher start
方法必须在主线程调用,子线程调用会抛出异常。setTimeOutMillion
方法是配合 await() 方法使用的,单独调用没有任何效果,表示 await 等待的超时时间await
阻塞当前线程,等待所有任务执行完毕之后,会自动往下走await()
方法必须在 start 方法之后调用setThreadPoolExecutor
设置 task 执行的线程池
AnchorTask 介绍
AnchorTask 实现了 IAnchorTask 接口,主要有几个方法
isRunOnMainThread(): Boolean
表示是否在主线程运行,默认值是 falsepriority(): Int
方法 表示线程的优先级别,默认值是 Process.THREAD_PRIORITY_FOREGROUNDneedWait()
表示当我们调用AnchorTaskDispatcher await
时,是否需要等待,return true,表示需要等待改任务执行结束,AnchorTaskDispatcher await
方法才能继续往下执行。fun getDependsTaskList(): List<class>?</class
方法返回前置任务依赖,默认值是返回 null.fun run()
方法,表示任务执行的时候
1interface IAnchorTask : IAnchorCallBack
2
3 /**
4 * 是否在主线程执行
5 */
6 fun isRunOnMainThread(): Boolean
7
8 /**
9 * 任务优先级别
10 */
11 @IntRange(
12 from = Process.THREAD_PRIORITY_FOREGROUND.toLong(),
13 to = Process.THREAD_PRIORITY_LOWEST.toLong()
14 )
15 fun priority(): Int
16
17 /**
18 * 调用 await 方法,是否需要等待改任务执行完成
19 * true 不需要
20 * false 需要
21 */
22 fun needWait(): Boolean
23
24 /**
25 * 当前任务的前置任务,可以用来确定顶点的入度
26 */
27 fun getDependsTaskList(): List<Class<out AnchorTask>>?
28
29 /**
30 * 任务被执行的时候回调
31 */
32 fun run()
33
34
1class AnchorTaskOne : AnchorTask()
2 override fun isRunOnMainThread(): Boolean
3 return false
4
5
6 override fun run()
7 val start = System.currentTimeMillis()
8 try
9 Thread.sleep(300)
10 catch (e: Exception)
11
12 LogUtils.i(
13 TAG, "AnchorTaskOne: " + (System.currentTimeMillis() - start)
14 )
15
16
17
监听任务的回调
1val anchorTask = AnchorTaskTwo()
2 anchorTask.addCallback(object : IAnchorCallBack
3 override fun onAdd()
4 com.xj.anchortask.LogUtils.i(TAG, "onAdd: $anchorTask")
5
6
7 override fun onRemove()
8 com.xj.anchortask.LogUtils.i(TAG, "onRemove: $anchorTask")
9
10
11 override fun onStart()
12 com.xj.anchortask.LogUtils.i(TAG, "onStart:$anchorTask ")
13
14
15 override fun onFinish()
16 com.xj.anchortask.LogUtils.i(TAG, "onFinish:$anchorTask ")
17
18
19 )
小结
这篇博客介绍了 AnchorTask 的使用,
AnchorTask 源码已经更新到 github,https://github.com/gdutxiaoxu/AnchorTask,下一篇,将输出 Android 启动优化(四)- 手把手教你实现 AnchorTask,敬请期待。AnchorTask 使用说明
Android 启动优化(二) - 拓扑排序的原理以及解题思路
以上是关于Android 启动优化- AnchorTask 开源了的主要内容,如果未能解决你的问题,请参考以下文章
Android 启动优化- AnchorTask 1.0.0 版本正式发布了
Android内核开发:系统启动速度优化-Android OS启动优化(转)