共计 3295 个字符,预计需要花费 9 分钟才能阅读完成。
微信公众号:徐公,本文首发我的微信公众号,有趣味的能够点此扫码关注
前两篇博客介绍了 Android 启动优化多线程异步加载依赖问题的解决方案 – 有向无环图,以及如何实现有它。明天,让咱们一起来看一下,在 Android 实战中,怎么实现。
Android 启动优化(一)– 有向无环图
Android 启动优化(二)– 拓扑排序的原理以及解题思路
简介
Android 启动优化,大家第一工夫可能会想到异步加载。将耗时工作放到子线程加载,等到所有加载工作加载实现之后,再进入首页。
多线程异步加载计划的确是 ok 的。但如果遇到前后依赖的关系呢。比方工作 2 依赖于工作 1,这时候要怎么解决呢。
这时候就能够应用 AnchorTask 解决,它的实现原理是构建一个有向无环图,拓扑排序之后,如果工作 B 依赖工作 A,那么 A 肯定排在工作 B 之后。
根本应用
第一步:在 moulde build.gradle 配置近程依赖
implementation 'com.xj.android:anchortask:0.1.0'
最新的版本号能够看这里 lastedt version
第二步:自定义 AnchorTaskB,继承 AnchorTask,重写相应的办法
class AnchorTaskB : AnchorTask() {override fun isRunOnMainThread(): Boolean {return false}
override fun run() {val start = System.currentTimeMillis()
try {
// 在这里进行操作,这里通过睡眠模仿耗时操作
Thread.sleep(300)
} catch (e: Exception) { }
com.xj.anchortask.library.log.LogUtils.i(TAG, "AnchorTaskOne:" + (System.currentTimeMillis() - start)
)
}
// 返回依赖的工作,这里是通过 class name 去找到对应的 task
override fun getDependsTaskList(): List<Class<out AnchorTask>>? {return ArrayList<Class<out AnchorTask>>().apply {add(AnchorTaskA::class.java)
}
}
}
如果工作 C 依赖工作 B,工作 A,能够这样写
class AnchorTaskC : AnchorTask() {override fun getDependsTaskList(): List<Class<out AnchorTask>>? {return ArrayList<Class<out AnchorTask>>().apply {add(AnchorTaskA::class.java)
add(AnchorTaskB::class.java)
}
}
}
最初,通过 AnchorTaskDispatcher.instance .addTask(AnchorTaskFive())
增加工作,并调用 start() 办法启动,await() 办法示意阻塞期待所有工作执行结束。
AnchorTaskDispatcher.instance.setContext(this).setLogLevel(LogUtils.LogLevel.DEBUG).setTimeOutMillion(1000L).
.addTask(AnchorTaskZero())
.addTask(AnchorTaskOne())
.addTask(AnchorTaskTwo())
.addTask(AnchorTaskThree())
.addTask(AnchorTaskFour())
.addTask(AnchorTaskFive())
.start()
.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<out AnchorTask>>?
办法返回前置工作依赖,默认值是返回 null.fun run()
办法,示意工作执行的时候
interface IAnchorTask : IAnchorCallBack {
/**
* 是否在主线程执行
*/
fun isRunOnMainThread(): Boolean
/**
* 工作优先级别
*/
@IntRange(from = Process.THREAD_PRIORITY_FOREGROUND.toLong(),
to = Process.THREAD_PRIORITY_LOWEST.toLong())
fun priority(): Int
/**
* 调用 await 办法,是否须要期待改工作执行实现
* true 不须要
* false 须要
*/
fun needWait(): Boolean
/**
* 当前任务的前置工作,能够用来确定顶点的入度
*/
fun getDependsTaskList(): List<Class<out AnchorTask>>?
/**
* 工作被执行的时候回调
*/
fun run()}
class AnchorTaskOne : AnchorTask() {override fun isRunOnMainThread(): Boolean {return false}
override fun run() {val start = System.currentTimeMillis()
try {Thread.sleep(300)
} catch (e: Exception) { }
LogUtils.i(TAG, "AnchorTaskOne:" + (System.currentTimeMillis() - start)
)
}
}
监听工作的回调
val anchorTask = AnchorTaskTwo()
anchorTask.addCallback(object : IAnchorCallBack {override fun onAdd() {com.xj.anchortask.LogUtils.i(TAG, "onAdd: $anchorTask")
}
override fun onRemove() {com.xj.anchortask.LogUtils.i(TAG, "onRemove: $anchorTask")
}
override fun onStart() {com.xj.anchortask.LogUtils.i(TAG, "onStart:$anchorTask")
}
override fun onFinish() {com.xj.anchortask.LogUtils.i(TAG, "onFinish:$anchorTask")
}
})
小结
这篇博客介绍了 AnchorTask 的应用,
AnchorTask 源码曾经更新到 github,AnchorTask,下一篇,将输入 Android 启动优化(四)- 手把手教你实现 AnchorTask,敬请期待。AnchorTask 应用阐明
我的微信公众号 程序员徐公,有趣味的能够点击扫码关注