Tutorial de aprendizaje de dardos para desarrolladores de Android

Prefacio

El sábado pasado, comí la comida equivocada, repentinamente mareado, fiebre, vómitos repentinos en medio de la noche, diarrea, toda la persona estaba bastante agitada. Fui al hospital para un examen y dije que fue causado por enteritis xx y por comer la comida equivocada, me quedé en casa y descansé cuatro días.

Hoy, finalmente llegó. Actualice el último artículo de la serie de gráficos acíclicos dirigidos a la optimización de inicio de Android. Recientemente, los artículos en esta área no se actualizarán por el momento. La serie de artículos se resume a continuación:

Optimización de inicio de Android (1): gráfico acíclico dirigido

Optimización de inicio de Android (dos): el principio de clasificación topológica e ideas para la resolución de problemas

Optimización de inicio de Android (3) -Instrucciones de AnchorTask

Optimización de inicio de Android (4): enséñele cómo implementar AnchorTask

Notas de lanzamiento

  1. Versión preconfigurada anterior a las tareas dependientes 0.1.0, por AnchorTask getDependsTaskListcierto, ha terminado classNamepara encontrar AnchorTasky cohesión en el AnchorTask actual, desde un punto de vista global, este enfoque no es muy intuitivo, 1.0.0 abandonó formas, Ali Alphacamino de referencia a travésaddTask(TASK_NAME_THREE).afterTask(TASK_NAME_ZERO, TASK_NAME_ONE)
  2. La versión 1.0.0 agrega la clase Project y aumenta la OnProjectExecuteListenerescucha
  3. OnGetMonitorRecordCallbackMonitor de la nueva versión 1.0.0 , facilita las estadísticas de cada tarea lleva

Descripción

Optimización de inicio de Android, puede pensar en la carga asincrónica por primera vez. Coloque las tareas que requieren mucho tiempo en el subproceso para cargar y luego ingrese a la página de inicio después de que se carguen todas las tareas de carga.

El esquema de carga asíncrono de subprocesos múltiples está bien. Pero, ¿qué pasa si se encuentra con una relación de dependencia? Por ejemplo, la tarea 2 depende de la tarea 1. ¿Cómo resolverla en este momento?

Supongamos que tenemos tal dependencia de tareas

Cómo lo usamos

        val project =
            AnchorProject.Builder().setContext(context).setLogLevel(LogUtils.LogLevel.DEBUG)
                .setAnchorTaskCreator(ApplicationAnchorTaskCreator())
                .addTask(TASK_NAME_ZERO)
                .addTask(TASK_NAME_ONE)
                .addTask(TASK_NAME_TWO)
                .addTask(TASK_NAME_THREE).afterTask(TASK_NAME_ZERO, TASK_NAME_ONE)
                .addTask(TASK_NAME_FOUR).afterTask(TASK_NAME_ONE, TASK_NAME_TWO)
                .addTask(TASK_NAME_FIVE).afterTask(TASK_NAME_THREE, TASK_NAME_FOUR)
                .build()
        project.start().await()
复制代码
class ApplicationAnchorTaskCreator : IAnchorTaskCreator {
    override fun createTask(taskName: String): AnchorTask? {
        when (taskName) {
            TASK_NAME_ZERO -> {
                return AnchorTaskZero()
            }

            TASK_NAME_ONE -> {
                return AnchorTaskOne()
            }
            TASK_NAME_TWO -> {
                return AnchorTaskTwo()
            }
            TASK_NAME_THREE -> {
                return AnchorTaskThree()
            }
            TASK_NAME_FOUR -> {
                return AnchorTaskFour()
            }
            TASK_NAME_FIVE -> {
                return AnchorTaskFive()
            }
        }
        return null
    }

}
复制代码

Cuando se ejecuta la demostración, puede ver el efecto esperado.

Uso basico

Paso 1: configurar dependencias remotas en moulde build.gradle

implementation 'com.xj.android:anchortask:1.0.0'
复制代码

El último número de versión se puede encontrar aquí última versión

Paso dos: personalizado AnchorTaskZero, heredado AnchorTasky específico taskName, la atención taskNamedebe ser única, porque estaremos de acuerdo con taskNameel AnchorTaskmétodo correspondiente para encontrar el método de anulación apropiado.

class AnchorTaskZero() : AnchorTask(TASK_NAME_ZERO) {
    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)
        )
    }
}
复制代码

Si la tarea tres depende de la tarea dos y la tarea uno, puede escribir así

addTask(TASK_NAME_THREE).afterTask(TASK_NAME_ZERO, TASK_NAME_ONE)
复制代码

Finalmente, el project.start()método se inicia, si es necesario bloquear la espera, llamar al método await ()

AnchorProject.Builder().setContext(context).setLogLevel(LogUtils.LogLevel.DEBUG)
                .setAnchorTaskCreator(ApplicationAnchorTaskCreator())
                .addTask(TASK_NAME_ZERO)
                .addTask(TASK_NAME_ONE)
                .addTask(TASK_NAME_TWO)
                .addTask(TASK_NAME_THREE).afterTask(TASK_NAME_ZERO, TASK_NAME_ONE)
                .addTask(TASK_NAME_FOUR).afterTask(TASK_NAME_ONE, TASK_NAME_TWO)
                .addTask(TASK_NAME_FIVE).afterTask(TASK_NAME_THREE, TASK_NAME_FOUR)
                .build()
project.start().await()
复制代码

Supervisar devolución de llamada de tarea

project.addListener(object : OnProjectExecuteListener {

            // project 开始执行的时候
            override fun onProjectStart() {
                com.xj.anchortask.LogUtils.i(MyApplication.TAG, "onProjectStart ")
            }

            // project 执行一个 task 完成的时候
            override fun onTaskFinish(taskName: String) {
                com.xj.anchortask.LogUtils.i(
                    MyApplication.TAG,
                    "onTaskFinish, taskName is $taskName"
                )
            }

            // project 执行完成的时候
            override fun onProjectFinish() {
                com.xj.anchortask.LogUtils.i(MyApplication.TAG, "onProjectFinish ")
            }

        })
复制代码

Agregue una devolución de llamada que requiere mucho tiempo para cada ejecución de tarea

project.onGetMonitorRecordCallback = object : OnGetMonitorRecordCallback {

            // 所有 task 执行完毕会调用这个方法,Map 存储了 task 的执行时间, key 是 taskName,value 是时间,单位毫秒
            override fun onGetTaskExecuteRecord(result: Map<String?, Long?>?) {
                onGetMonitorRecordCallback?.onGetTaskExecuteRecord(result)
            }

            // 所有 task 执行完毕会调用这个方法,costTime 执行时间
            override fun onGetProjectExecuteTime(costTime: Long) {
                onGetMonitorRecordCallback?.onGetProjectExecuteTime(costTime)
            }

        }
复制代码

Introducción al AnchorProject

  1. AnchorTaskDispatcher start El método debe llamarse en el subproceso principal y las llamadas al subproceso arrojarán una excepción.
  2. await Bloquea el hilo actual, espera a que se ejecuten todas las tareas y luego baja automáticamente, el método de espera lleva un parámetro, timeOutMillion representa el tiempo de espera de tiempo de espera
  3. await() El método debe llamarse después del método de inicio
  4. Agregar una tarea AnchorProject.Builder().addTaskagregando un modo de configuración típico
  5. Configure el grupo de subprocesos para la ejecución, puede pasar AnchorProject.Builder().setThreadPoolExecutor(TaskExecutorManager.instance.cpuThreadPoolExecutor)

Introducción a AnchorTask

AnchorTask implementa la interfaz IAnchorTask, hay varios métodos principales

  • isRunOnMainThread(): BooleanIndica si se ejecutará en el hilo principal, el valor predeterminado es falso
  • priority(): Int El método indica el nivel de prioridad del hilo, el valor predeterminado es Process.THREAD_PRIORITY_FOREGROUND
  • needWait()Significa que cuando llamamos AnchorTaskDispatcher await, si esperar, devolver verdadero, expresó la necesidad de esperar al final para cambiar la ejecución de la tarea, AnchorTaskDispatcher awaitel método puede continuar con la implementación.
  • fun run() Método, que significa cuándo se ejecuta la tarea
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 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)
        )
    }

}
复制代码

La devolución de llamada de la tarea de supervisión

val anchorTask = AnchorTaskTwo()
        anchorTask.addCallback(object : IAnchorCallBack {
            override fun onAdd() {
                com.xj.anchortask.LogUtils.i(TAG, "onAdd: $anchorTask")
            }

            override fun onStart() {
                com.xj.anchortask.LogUtils.i(TAG, "onStart:$anchorTask ")
            }

            override fun onFinish() {
                com.xj.anchortask.LogUtils.i(TAG, "onFinish:$anchorTask ")
            }

        })
复制代码

para resumir

El principio de AnchorTask no es complicado, y la esencia es la combinación de un gráfico acíclico dirigido y conocimiento multiproceso.

  1. Construya un gráfico acíclico dirigido según BFS y obtenga su clasificación topológica
  2. En el proceso de ejecución multiproceso, aseguramos la relación de ejecución secuencial a través de la relación de subtarea de la tarea y CounDownLatch
    1. Si la tarea predecesora no se ha ejecutado, espere, si la ejecución se ha completado, baje
    2. Realizar tareas
    3. Notifique a la subtarea que la tarea actual se completó y el contador correspondiente (en grados) debería reducirse en uno.

Más desarrollo de Android bienvenido a unirse a nuestro círculo de aprendizaje avanzado de Android

Supongo que te gusta

Origin blog.csdn.net/weixin_43901866/article/details/114371517
Recomendado
Clasificación