|
|
@@ -1,242 +0,0 @@
|
|
|
-package com.adealink.frame.startup.dispatcher
|
|
|
-
|
|
|
-import android.os.Looper
|
|
|
-import com.adealink.frame.base.AppBaseInfo
|
|
|
-import com.adealink.frame.log.Log
|
|
|
-import com.adealink.frame.startup.TAG_START_UP
|
|
|
-import com.adealink.frame.startup.executor.TaskExecutorManager
|
|
|
-import com.adealink.frame.startup.runnable.StartTaskRunnable
|
|
|
-import com.adealink.frame.startup.task.StartUpTask
|
|
|
-import com.adealink.frame.startup.util.StartUpTaskSortUtil.getSortResult
|
|
|
-import com.adealink.frame.util.isMainThread
|
|
|
-import java.util.concurrent.CountDownLatch
|
|
|
-import java.util.concurrent.LinkedBlockingQueue
|
|
|
-import java.util.concurrent.TimeUnit
|
|
|
-import java.util.concurrent.atomic.AtomicInteger
|
|
|
-
|
|
|
-class StartTaskDispatcher private constructor() {
|
|
|
- //存放每个Task (key= Class < ? extends AppStartTask>)
|
|
|
- private val mTaskHashMap = HashMap<Class<out StartUpTask>, StartUpTask>()
|
|
|
-
|
|
|
- //每个Task的孩子 (key= Class < ? extends AppStartTask>)
|
|
|
- private val mTaskChildHashMap = HashMap<Class<out StartUpTask>, MutableList<Class<out StartUpTask>>>()
|
|
|
-
|
|
|
- //通过Add添加进来的所有任务
|
|
|
- private val mStartTaskList: MutableList<StartUpTask> = ArrayList()
|
|
|
-
|
|
|
- //拓扑排序后的所有任务
|
|
|
- private var mSortTaskList: List<StartUpTask>? = null
|
|
|
-
|
|
|
- //拓扑排序后的主线程的任务
|
|
|
- private val mSortMainThreadTaskList: MutableList<StartUpTask> = ArrayList()
|
|
|
- private val mMainThreadTaskCount = AtomicInteger()
|
|
|
-
|
|
|
- //拓扑排序后的子线程的任务
|
|
|
- private val mSortThreadPoolTaskList: MutableList<StartUpTask> = ArrayList()
|
|
|
-
|
|
|
- //待执行的任务
|
|
|
- private val mPendingTaskList: LinkedBlockingQueue<StartUpTask> = LinkedBlockingQueue()
|
|
|
-
|
|
|
- //需要等待的任务总数,用于阻塞
|
|
|
- private var mCountDownLatch: CountDownLatch? = null
|
|
|
-
|
|
|
- //需要等待的任务总数,用于CountDownLatch
|
|
|
- private val mNeedWaitCount = AtomicInteger()
|
|
|
-
|
|
|
- //所有的任务开始时间,结束时间
|
|
|
- private var mStartTime: Long = 0
|
|
|
- private var mFinishTime: Long = 0
|
|
|
- private var mAllTaskTime: Long = 0
|
|
|
-
|
|
|
- //所有阻塞任务的总超时时间
|
|
|
- private var mAllTaskWaitTimeOut = WAITING_TIME
|
|
|
-
|
|
|
- fun setAllTaskWaitTimeOut(allTaskWaitTimeOut: Long): StartTaskDispatcher {
|
|
|
- mAllTaskWaitTimeOut = allTaskWaitTimeOut
|
|
|
- return this
|
|
|
- }
|
|
|
-
|
|
|
- fun addAppStartTask(startUpTask: StartUpTask?): StartTaskDispatcher {
|
|
|
- if (startUpTask == null) {
|
|
|
- throw RuntimeException("addAppStartTask() 传入的appStartTask为null")
|
|
|
- }
|
|
|
- mStartTaskList.add(startUpTask)
|
|
|
- if (ifNeedWait(startUpTask)) {
|
|
|
- mNeedWaitCount.getAndIncrement()
|
|
|
- }
|
|
|
- return this
|
|
|
- }
|
|
|
-
|
|
|
- fun start(): StartTaskDispatcher {
|
|
|
- if (Looper.getMainLooper() != Looper.myLooper()) {
|
|
|
- throw RuntimeException("start() must called on MainThread")
|
|
|
- }
|
|
|
- mStartTime = System.currentTimeMillis()
|
|
|
- //拓扑排序,拿到排好序之后的任务队列
|
|
|
- mSortTaskList = getSortResult(mStartTaskList, mTaskHashMap, mTaskChildHashMap)
|
|
|
- initRealSortTask()
|
|
|
- printSortTask()
|
|
|
- mCountDownLatch = CountDownLatch(mNeedWaitCount.get())
|
|
|
-
|
|
|
- Log.i(TAG_START_UP, "start(), mStartTime:$mStartTime, mNeedWaitCount:${mNeedWaitCount.get()}")
|
|
|
- dispatchAppStartTask()
|
|
|
- return this
|
|
|
- }
|
|
|
-
|
|
|
- //分别处理主线程和子线程的任务
|
|
|
- private fun initRealSortTask() {
|
|
|
- val sortTaskList = mSortTaskList
|
|
|
- if (sortTaskList.isNullOrEmpty()) {
|
|
|
- return
|
|
|
- }
|
|
|
- for (appStartTask in sortTaskList) {
|
|
|
- if (appStartTask.isRunOnMainThread) {
|
|
|
- mSortMainThreadTaskList.add(appStartTask)
|
|
|
- mMainThreadTaskCount.getAndIncrement()
|
|
|
- } else {
|
|
|
- mSortThreadPoolTaskList.add(appStartTask)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //输出排好序的Task
|
|
|
- private fun printSortTask() {
|
|
|
- if (AppBaseInfo.isRelease) {
|
|
|
- return
|
|
|
- }
|
|
|
- val sb = StringBuilder()
|
|
|
- sb.append("printSortedTask():")
|
|
|
- val sortTaskList = mSortTaskList ?: emptyList()
|
|
|
- for (i in sortTaskList.indices) {
|
|
|
- val taskName = sortTaskList[i].javaClass.simpleName
|
|
|
- if (i != 0) {
|
|
|
- sb.append("--->")
|
|
|
- }
|
|
|
- sb.append(taskName)
|
|
|
- }
|
|
|
- Log.i(TAG_START_UP, sb.toString())
|
|
|
-
|
|
|
- val mainTaskSb = StringBuilder()
|
|
|
- mainTaskSb.append(" MainThread Task List: ")
|
|
|
- for (i in mSortMainThreadTaskList.indices) {
|
|
|
- val taskName = mSortMainThreadTaskList[i].javaClass.simpleName
|
|
|
- if (i != 0) {
|
|
|
- mainTaskSb.append("--->")
|
|
|
- }
|
|
|
- mainTaskSb.append(taskName)
|
|
|
- }
|
|
|
- Log.i(TAG_START_UP, mainTaskSb.toString())
|
|
|
-
|
|
|
- val threadTaskSb = StringBuilder()
|
|
|
- threadTaskSb.append(" SubThread Task List: ")
|
|
|
- for (i in mSortThreadPoolTaskList.indices) {
|
|
|
- val taskName = mSortThreadPoolTaskList[i].javaClass.simpleName
|
|
|
- if (i != 0) {
|
|
|
- threadTaskSb.append("--->")
|
|
|
- }
|
|
|
- threadTaskSb.append(taskName)
|
|
|
- }
|
|
|
- Log.i(TAG_START_UP, threadTaskSb.toString())
|
|
|
- }
|
|
|
-
|
|
|
- //发送任务
|
|
|
- private fun dispatchAppStartTask() {
|
|
|
- //先发送非主线程的任务
|
|
|
- var maxSubTaskCount = TaskExecutorManager.instance.getMaxTaskCount()
|
|
|
- Log.d(TAG_START_UP, "dispatchAppStartTask, maxSubTaskCount:$maxSubTaskCount")
|
|
|
- for (appStartTask in mSortThreadPoolTaskList) {
|
|
|
- if (maxSubTaskCount > 0) {
|
|
|
- maxSubTaskCount--
|
|
|
- appStartTask.runOnExecutor().execute(StartTaskRunnable(appStartTask, this))
|
|
|
- } else {
|
|
|
- //线程池负荷过高,将任务加入待执行任务
|
|
|
- mPendingTaskList.offer(appStartTask)
|
|
|
- }
|
|
|
- }
|
|
|
- Log.d(
|
|
|
- TAG_START_UP, "dispatchAppStartTask, mPendingTaskList :${
|
|
|
- mPendingTaskList.joinToString(separator = ",", transform = {
|
|
|
- it::class.java.name
|
|
|
- })
|
|
|
- }"
|
|
|
- )
|
|
|
- //再发送主线程的任务,防止主线程任务阻塞,导致子线程任务不能立刻执行
|
|
|
- for (appStartTask in mSortMainThreadTaskList) {
|
|
|
- StartTaskRunnable(appStartTask, this).run()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //通知Children一个前置任务已完成
|
|
|
- fun setNotifyChildren(startUpTask: StartUpTask) {
|
|
|
- val arrayList = mTaskChildHashMap[startUpTask.javaClass]
|
|
|
- if (arrayList != null && arrayList.size > 0) {
|
|
|
- for (aclass in arrayList) {
|
|
|
- mTaskHashMap[aclass]?.notifyDependFinish()
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //标记已经完成的Task
|
|
|
- fun markAppStartTaskFinish(startUpTask: StartUpTask, taskCostTime: Long) {
|
|
|
- if (ifNeedWait(startUpTask)) {
|
|
|
- mCountDownLatch?.countDown()
|
|
|
- mNeedWaitCount.getAndDecrement()
|
|
|
- }
|
|
|
- mAllTaskTime += taskCostTime
|
|
|
- Log.i(TAG_START_UP, "markAppStartTaskFinish, ${startUpTask::class.java}, mNeedWaitCount:${mNeedWaitCount.get()}")
|
|
|
- if (isMainThread()) {
|
|
|
- val mainThreadCount = mMainThreadTaskCount.decrementAndGet()
|
|
|
- Log.d(TAG_START_UP, ">>>> mainThreadCount(${mainThreadCount})")
|
|
|
- if (mainThreadCount == 0) {
|
|
|
- tryRunTaskOnMainThread()
|
|
|
- }
|
|
|
- } else {
|
|
|
- tryRunTaskOnSubThread()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private fun tryRunTaskOnMainThread() {
|
|
|
- //主线程执行完任务了,看看是否有待执行的任务
|
|
|
- val pendingTask = mPendingTaskList.poll()
|
|
|
- if (pendingTask != null) {
|
|
|
- Log.d(TAG_START_UP, "mPendingTask(${pendingTask::class.java}) => MainThread")
|
|
|
- mMainThreadTaskCount.getAndIncrement()
|
|
|
- StartTaskRunnable(pendingTask, this).run()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private fun tryRunTaskOnSubThread() {
|
|
|
- val pendingTask = mPendingTaskList.poll()
|
|
|
- if (pendingTask != null) {
|
|
|
- Log.d(TAG_START_UP, "mPendingTask(${pendingTask::class.java}) => ThreadPool")
|
|
|
- pendingTask.runOnExecutor().execute(StartTaskRunnable(pendingTask, this))
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //是否需要等待,主线程的任务本来就是阻塞的,所以不用管
|
|
|
- private fun ifNeedWait(task: StartUpTask): Boolean {
|
|
|
- return task.isRunOnMainThread || task.needWait()
|
|
|
- }
|
|
|
-
|
|
|
- //等待,阻塞主线程
|
|
|
- fun await() {
|
|
|
- try {
|
|
|
- val countDownLatch = mCountDownLatch ?: throw RuntimeException("You must call start() before call await()")
|
|
|
- Log.i(TAG_START_UP, "await(), mAllTaskWaitTimeOut:$mAllTaskWaitTimeOut")
|
|
|
- countDownLatch.await(mAllTaskWaitTimeOut, TimeUnit.MILLISECONDS)
|
|
|
-
|
|
|
- mFinishTime = System.currentTimeMillis() - mStartTime
|
|
|
- Log.i(TAG_START_UP, "All waiting task finish, cost:${mFinishTime}ms, all cost:${mAllTaskTime}ms, save time:${mAllTaskTime - mFinishTime}ms")
|
|
|
- } catch (e: InterruptedException) {
|
|
|
- e.printStackTrace()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- companion object {
|
|
|
- //所有任务需要等待的时间
|
|
|
- private const val WAITING_TIME = 10_000L
|
|
|
- fun create(): StartTaskDispatcher {
|
|
|
- return StartTaskDispatcher()
|
|
|
- }
|
|
|
- }
|
|
|
-}
|