Wechat public number: Programmer Xu gong (Stormjun94), this article is the first of my wechat public number, interested can click here to scan code attention

The first two posts covered the Android startup solution to optimize multithreaded asynchronous loading dependencies – directed acyclic graphs – and how to implement it. Today, let’s take a look at how to implement Android in action.

Android Startup Optimization (1) – Directed acyclic graph

Android startup optimization (2) – Topology sort principle and solution ideas

Introduction to the

When Android starts optimization, asynchronous loading is probably the first thing that comes to mind. Load time-consuming tasks in sub-threads and enter the home page after all loading tasks are completed.

Multithreaded asynchronous loading schemes are indeed OK. But what if you have a dependency relationship. Let’s say task 2 depends on task 1.

In this case, AnchorTask can be used to solve the problem. Its implementation principle is to build A directed acyclic graph. After topological sorting, if task B depends on task A, then TASK A must be ranked after task B.

The basic use

Step 1: Configure remote dependencies in moulde build.gradle

Implementation 'com. Xj. Android: anchortask: 0.1.0 from'Copy the code

For the latest version, see lastedt Version here

Step 2: Customize AnchorTaskB, inherit AnchorTask, and override the corresponding methods

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))} override Fun getDependsTaskList(): List<Class<out AnchorTask>>? { return ArrayList<Class<out AnchorTask>>().apply { add(AnchorTaskA::class.java) } } }Copy the code

If task C depends on task B, task A, we could write it this way

class AnchorTaskC : AnchorTask() {
   
    override fun getDependsTaskList(): List<Class<out AnchorTask>>? {
        return ArrayList<Class<out AnchorTask>>().apply {
            add(AnchorTaskA::class.java)
            add(AnchorTaskB::class.java)
        }
    }

}
Copy the code

Finally, by AnchorTaskDispatcher. Instance. AddTask (AnchorTaskFive (), add tasks, and calls the start () method starts, await () method of the said blocking wait for all tasks to complete.

AnchorTaskDispatcher.instance.setContext(this).setLogLevel(LogUtils.LogLevel.DEBUG).setTimeOutMillion(1000L).
            .addTask(AnchorTaskZero())
            .addTask(AnchorTaskOne())
            .addTask(AnchorTaskTwo())
            .addTask(AnchorTaskThree())
            .addTask(AnchorTaskFour())
            .addTask(AnchorTaskFive())
            .start()
            .await()
Copy the code

AnchorTaskDispatcher introduction

  1. AnchorTaskDispatcher startMethod must be called on the main thread, and child thread calls throw exceptions.
  2. setTimeOutMillionMethod is used in conjunction with the await() method, calling it alone has no effect and represents the timeout to await the await
  3. awaitBlock the current thread, waiting for all tasks to complete, will automatically go down
  4. await()Method must be called after the start method
  5. setThreadPoolExecutorSet the thread pool for task execution

AnchorTask introduction

AnchorTask implements the IAnchorTask interface in several main ways

  • isRunOnMainThread(): BooleanIndicates whether to run on the main thread. The default value is false
  • priority(): IntThe process.thread_priority_foreground method represents the priority level of the thread. The default value is process.thread_priority_foreground
  • needWait()Represents when we callAnchorTaskDispatcher awaitReturn true: indicates that the change task needs to be completed.AnchorTaskDispatcher awaitMethod to continue execution.
  • fun getDependsTaskList(): List<Class<out AnchorTask>>?The pretask dependency method returns null by default.
  • fun run()Method when the task is executed
Interface IAnchorTask: IAnchorCallBack {/** * whether to execute on the main thread */ fun isRunOnMainThread(): */ @intrange (from = process.thread_priority_foreground. ToLong (), to = Process.THREAD_PRIORITY_LOWEST.toLong() ) fun priority(): Int /** * to call await method, do I need to wait for the task to complete? Boolean /** * A pre-task for the current task, which can be used to determine the entry degree of the vertex */ getDependsTaskList(): List<Class<out AnchorTask>>? /** * Callback when the task is executed */ fun run()}Copy the code
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) ) } }Copy the code

Listen for the callback of the task

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 ")
            }

        })
Copy the code

summary

This blog introduces the use of AnchorTask, the source code has been updated to Github, AnchorTask, the next post, will output Android startup optimization (4) – hand guide to implementing AnchorTask, stay tuned. AnchorTask instructions

My wechat public number programmer Xu Gong, interested can click scan code attention