In depth exploration of Android startup optimization (V) – anchortask version 1.0.0 has been officially released

Time:2022-5-10
In depth exploration of Android startup optimization (V) - anchortask version 1.0.0 has been officially released

Today, update the last article in the Android startup optimization directed acyclic graph series. The article series is summarized as follows:

Android startup optimization (I) – directed acyclic graph

Android startup optimization (II) – the principle of topology sorting and problem solving ideas

Android startup optimization (III) – anchortask is open source

Android startup optimization (IV) – how is anchortask implemented

Update description

  1. Previous versions of 0.1.0 configured pre dependency tasks throughAnchorTask getDependsTaskListThe way he is throughclassNamefindAnchorTask, and it is cohesive in the current anchortask. From a global perspective, this method is not intuitive. 1.0.0 abandoned this method. Refer to AlibabaAlphaBy way ofaddTask(TASK_NAME_THREE).afterTask(TASK_NAME_ZERO, TASK_NAME_ONE)

  2. In version 1.0.0, the project class is added andOnProjectExecuteListenermonitor

  3. New in version 1.0.0OnGetMonitorRecordCallbackMonitoring to facilitate the time-consuming statistics of various tasks

explain

You may think of asynchronous loading time first. Put the time-consuming tasks into the sub thread to load, and then enter the home page after all the loading tasks are loaded.

The multithreaded asynchronous loading scheme is indeed OK. But what if you encounter a dependency relationship. For example, task 2 depends on task 1. How to solve it at this time.

Suppose we have such task dependencies

In depth exploration of Android startup optimization (V) - anchortask version 1.0.0 has been officially released

How do we use it

 1        val project =
 2            AnchorProject.Builder().setContext(context).setLogLevel(LogUtils.LogLevel.DEBUG)
 3                .setAnchorTaskCreator(ApplicationAnchorTaskCreator())
 4                .addTask(TASK_NAME_ZERO)
 5                .addTask(TASK_NAME_ONE)
 6                .addTask(TASK_NAME_TWO)
 7                .addTask(TASK_NAME_THREE).afterTask(TASK_NAME_ZERO, TASK_NAME_ONE)
 8                .addTask(TASK_NAME_FOUR).afterTask(TASK_NAME_ONE, TASK_NAME_TWO)
 9                .addTask(TASK_NAME_FIVE).afterTask(TASK_NAME_THREE, TASK_NAME_FOUR)
10                .build()
11        project.start().await()
In depth exploration of Android startup optimization (V) - anchortask version 1.0.0 has been officially released

image.gif
 1class ApplicationAnchorTaskCreator : IAnchorTaskCreator {
 2    override fun createTask(taskName: String): AnchorTask? {
 3        when (taskName) {
 4            TASK_NAME_ZERO -> {
 5                return AnchorTaskZero()
 6            }
 7
 8            TASK_NAME_ONE -> {
 9                return AnchorTaskOne()
10            }
11            TASK_NAME_TWO -> {
12                return AnchorTaskTwo()
13            }
14            TASK_NAME_THREE -> {
15                return AnchorTaskThree()
16            }
17            TASK_NAME_FOUR -> {
18                return AnchorTaskFour()
19            }
20            TASK_NAME_FIVE -> {
21                return AnchorTaskFive()
22            }
23        }
24        return null
25    }
26
27}

When the demo runs, you can see the expected effect.

In depth exploration of Android startup optimization (V) - anchortask version 1.0.0 has been officially released

Basic use

Step 1: in moulde build Gradle configuration remote dependency

1implementation 'com.xj.android:anchortask:1.0.0'

The latest version number can be found here

Step 2: CustomizeAnchorTaskZero, inheritAnchorTask, and specifytaskName, attentiontaskNameMust be unique, because we willtaskNameFind the appropriateAnchorTaskRewrite the corresponding method

 1class AnchorTaskZero() : AnchorTask(TASK_NAME_ZERO) {
 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}

If task 3 depends on Task 2 and task 1, it can be written like this

1addTask(TASK_NAME_THREE).afterTask(TASK_NAME_ZERO, TASK_NAME_ONE)

Finally, throughproject.start()Method starts. If you need to block and wait, call await () method

 1AnchorProject.Builder().setContext(context).setLogLevel(LogUtils.LogLevel.DEBUG)
 2                .setAnchorTaskCreator(ApplicationAnchorTaskCreator())
 3                .addTask(TASK_NAME_ZERO)
 4                .addTask(TASK_NAME_ONE)
 5                .addTask(TASK_NAME_TWO)
 6                .addTask(TASK_NAME_THREE).afterTask(TASK_NAME_ZERO, TASK_NAME_ONE)
 7                .addTask(TASK_NAME_FOUR).afterTask(TASK_NAME_ONE, TASK_NAME_TWO)
 8                .addTask(TASK_NAME_FIVE).afterTask(TASK_NAME_THREE, TASK_NAME_FOUR)
 9                .build()
10project.start().await()

Listening task callback

1project.addListener(object : OnProjectExecuteListener {
 2
 3 // when the project starts executing
 4            override fun onProjectStart() {
 5                com.xj.anchortask.LogUtils.i(MyApplication.TAG, "onProjectStart ")
 6            }
 7
 8 // when the project executes a task
 9            override fun onTaskFinish(taskName: String) {
10                com.xj.anchortask.LogUtils.i(
11                    MyApplication.TAG,
12                    "onTaskFinish, taskName is $taskName"
13                )
14            }
15
16 // when the project is completed
17            override fun onProjectFinish() {
18                com.xj.anchortask.LogUtils.i(MyApplication.TAG, "onProjectFinish ")
19            }
20
21        })

Add time consuming callback for each task execution

1project.onGetMonitorRecordCallback = object : OnGetMonitorRecordCallback {
 2
 3 // this method will be called after all tasks are executed. Map stores the execution time of the task. Key is taskname, value is time, and the unit is milliseconds
 4            override fun onGetTaskExecuteRecord(result: Map<String?, Long?>?) {
 5                onGetMonitorRecordCallback?.onGetTaskExecuteRecord(result)
 6            }
 7
 8 // this method will be called after all tasks are executed. Costtime is the execution time
 9            override fun onGetProjectExecuteTime(costTime: Long) {
10                onGetMonitorRecordCallback?.onGetProjectExecuteTime(costTime)
11            }
12
13        }

Introduction to anchor project

  1. AnchorTaskDispatcher startMethod must be called in the main thread, and the child thread will throw an exception.

  2. awaitBlocking the current thread and waiting for all tasks to be executed will automatically go down. The await method carries a parameter. Timeoutmillion indicates the timeout waiting time

  3. await()Method must be called after the start method

  4. Add tasks throughAnchorProject.Builder().addTaskAdded, typical construction mode

  5. To set the thread pool for execution, you canAnchorProject.Builder().setThreadPoolExecutor(TaskExecutorManager.instance.cpuThreadPoolExecutor)

Anchortask introduction

Anchortask implements the ianchortask interface. There are several main methods

  • isRunOnMainThread(): BooleanIndicates whether to run on the main thread. The default value is false

  • priority(): IntMethod represents the priority of the thread. The default value is process THREAD_ PRIORITY_ FOREGROUND

  • needWait()When we callAnchorTaskDispatcher awaitReturn TRUE indicates whether to wait for the completion of the modified task,AnchorTaskDispatcher awaitMethod to continue execution.

  • fun run()Method, indicating when the task is executed

1interface IAnchorTask : IAnchorCallBack {
 2
 3    /**
 4 * whether to execute in the main thread
 5     */
 6    fun isRunOnMainThread(): Boolean
 7
 8    /**
 9 * task priority
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 * when await method is called, do you need to wait for the change task to complete
19 * true not required
20 * false required
21     */
22    fun needWait(): Boolean
23
24    /**
25 * callback when the task is executed
26     */
27    fun run()
28
29}
 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}

Callback of listening task

 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 onStart() {
 8                com.xj.anchortask.LogUtils.i(TAG, "onStart:$anchorTask ")
 9            }
10
11            override fun onFinish() {
12                com.xj.anchortask.LogUtils.i(TAG, "onFinish:$anchorTask ")
13            }
14
15        })

summary

The principle of anchortask is not complex. Its essence is the combination of directed acyclic graph and multithreading knowledge.

  1. The directed acyclic graph is constructed according to BFS, and its topological order is obtained

  2. In the process of multithreading, we ensure the sequential execution relationship through the subtask relationship of the task and the coundownlatch

    1. If the pre task is not completed, wait. If the pre task is completed, go down

    2. Perform tasks

    3. Inform the subtask that the current task has been executed, and the corresponding counter (input degree) should be reduced by one.

AnchorTask:https://github.com/gdutxiaoxu/AnchorTask

If you want to see the specific implementation of version 1.0.0, you can see this article. Principle description of anchortask 1.0.0.

Android architect system learning notes, learning videos, bat factory interview questions:My GitHub

If you think it’s helpful to you, give me some praise + attention and support~~

In depth exploration of Android startup optimization (V) - anchortask version 1.0.0 has been officially released