微信公众号:程序员徐公(stormjun94),本文首发我的微信公众号,有兴趣的可以点击扫码关注
如果觉得对你有所帮助的,可以关注我的微信公众号,程序员徐公。主要更新 Android 技术,算法,职场相关的。
![图片[1]-Android 启动优化(三) - AnchorTask 使用说明 - 计算机毕业设计源码网-计算机毕业设计源码网](https://gitee.com/gdutxiaoxu/blog-picture/raw/master/21/01/qrcode_for_gh_f0b7a2d93f70_430%20(2).jpg)
前两篇博客介绍了 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表示是否在主线程运行,默认值是 false
- priority(): Int方法 表示线程的优先级别,默认值是 Process.THREAD_PRIORITY_FOREGROUND
- needWait()表示当我们调用- 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,敬请期待。
我的微信公众号程序员徐公,有兴趣的可以点击扫码关注












暂无评论内容