Kaynağa Gözat

feat: APP启动优化 (#27)

- 主线程+启动线程池一起协作完成启动任务
- 启动线程池设计任务阈值( = PoolExecutor.maximumPoolSize * 1.2 ), 没有加入处理队列的任务加入等待队列
- 当线程完成一项任务后, 查询等待队列,
  若等待队列为空, 主线程进入await, 子线程结束
- 任务类混淆
- MainStartUpFragment改为协程实现
DoggyZhang 7 ay önce
ebeveyn
işleme
5131fb31eb

+ 202 - 231
app/src/main/java/com/adealink/weparty/App.kt

@@ -3,14 +3,12 @@ package com.adealink.weparty
 import android.content.Context
 import android.content.SharedPreferences
 import android.content.res.Configuration
-import android.graphics.Bitmap
 import android.os.SystemClock
 import androidx.room.Room
 import com.adealink.frame.aab.AAB
 import com.adealink.frame.aab.util.getCompatString
 import com.adealink.frame.apm.initAPMService
 import com.adealink.frame.base.AppBaseInfo
-import com.adealink.frame.coroutine.dispatcher.Dispatcher
 import com.adealink.frame.crash.installCrashProtector
 import com.adealink.frame.data.json.initJsonConfig
 import com.adealink.frame.debug.datasource.performanceDataController
@@ -24,7 +22,6 @@ import com.adealink.frame.effect.createEffect
 import com.adealink.frame.effect.initEffect
 import com.adealink.frame.googleservice.createGoogleService
 import com.adealink.frame.image.imageService
-import com.adealink.frame.image.listener.IImageLoadResultListener
 import com.adealink.frame.imkit.IMService
 import com.adealink.frame.initStorageService
 import com.adealink.frame.locale.language.createLanguageManager
@@ -42,8 +39,8 @@ import com.adealink.frame.router.manager.deeplinkRouterManager
 import com.adealink.frame.security.createSecurityService
 import com.adealink.frame.share.initShareManager
 import com.adealink.frame.sound.createSoundPlayer
-import com.adealink.frame.startup.dispatcher.AppStartTaskDispatcher
-import com.adealink.frame.startup.task.AppStartTask
+import com.adealink.frame.startup.dispatcher.StartTaskDispatcher
+import com.adealink.frame.startup.task.StartUpTask
 import com.adealink.frame.statistics.report.initStat
 import com.adealink.frame.storageService
 import com.adealink.frame.tceffect.TCEffectManager
@@ -70,6 +67,7 @@ import com.adealink.weparty.deviceidservice.DeviceIdServiceConfig
 import com.adealink.weparty.deviceidservice.TCTuringConfig
 import com.adealink.weparty.download.DownloadConfig
 import com.adealink.weparty.effect.EffectConfig
+import com.adealink.weparty.effect.SVGA_CONFIG
 import com.adealink.weparty.effect.TCEffectConfig
 import com.adealink.weparty.googleservice.GoogleServiceConfig
 import com.adealink.weparty.hardware.HardwareManager
@@ -116,19 +114,9 @@ import com.gu.toolargetool.DefaultFormatter
 import com.gu.toolargetool.Logger
 import com.gu.toolargetool.TooLargeTool
 import com.opensource.svgaplayer.control.SVGAManager
-import com.opensource.svgaplayer.control.SvgaConfig
-import com.opensource.svgaplayer.disk.DiskCacheParamsSupplier
-import com.opensource.svgaplayer.disk.DiskTrimStrategy
-import com.opensource.svgaplayer.executor.ExecutorsSupplier
-import com.opensource.svgaplayer.remote.ImageFetchCallback
-import com.opensource.svgaplayer.remote.ImageFetcher
-import com.opensource.svgaplayer.utils.ByteConstants
 import com.tencent.mars.xlog.Xlog
 import io.rong.imlib.model.InitOption
 import me.weishu.reflection.Reflection
-import java.io.File
-import java.util.concurrent.Executor
-import java.util.concurrent.TimeUnit
 
 /**
  * Created by sunxiaodong on 2021/3/25.
@@ -176,8 +164,49 @@ class App : SplitCompatApplication(), ActivityLifecycleCallbacksExt {
         logTime(TAG_TIME_APP_START, "app attachBaseContext end")
     }
 
-    abstract inner class MainThreadStartTask : AppStartTask() {
-        override val isRunOnMainThread: Boolean = true
+    override fun onCreate() {
+        super.onCreate()
+        val appOnCreateTs = SystemClock.elapsedRealtime()
+        Log.i(TAG_TIME_APP_START, "app onCreate start")
+        //基础任务
+        baseStartTask()
+        //APP并发初始化任务
+        StartTaskDispatcher.create().apply {
+            addAppStartTask(InitNetwork())
+            addAppStartTask(InitPush())
+            addAppStartTask(InitUI())
+            addAppStartTask(InitTCEffect())
+            addAppStartTask(InitSVGA())
+            addAppStartTask(InitImageService())
+            addAppStartTask(InitRouter())
+            addAppStartTask(InitLanguage())
+            addAppStartTask(InitSecurityService())
+            addAppStartTask(InitGoogleService())
+            addAppStartTask(InitStorageService())
+            addAppStartTask(InitShareManager())
+            addAppStartTask(InitOssService())
+            addAppStartTask(InitJSBridgeManager())
+            addAppStartTask(InitWebResourceLoader())
+            addAppStartTask(InitDownloadService())
+            addAppStartTask(InitEffect())
+            addAppStartTask(InitFirebaseAnalytics())
+            addAppStartTask(InitFB())
+            addAppStartTask(InitPayerMax())
+
+            addAppStartTask(InitIM())
+            addAppStartTask(InitCall1())
+            addAppStartTask(InitCall2())
+            addAppStartTask(InitTCTuringManager())
+
+            //其他子任务(不卡主流程)
+            addAppStartTask(InitOther())
+
+            if (!AppBaseInfo.isRelease) {
+                addAppStartTask(InitDebugKit())
+            }
+
+        }.start().await()
+        Log.i(TAG_TIME_APP_START, "app onCreate end, cost:${SystemClock.elapsedRealtime() - appOnCreateTs}")
     }
 
     /**
@@ -185,112 +214,180 @@ class App : SplitCompatApplication(), ActivityLifecycleCallbacksExt {
      * - 日志
      * - 组件/模块配置
      */
-    inner class BaseStartTask : MainThreadStartTask() {
+    private fun baseStartTask() {
+        val startTs = SystemClock.elapsedRealtime()
+        Log.i(TAG_TIME_APP_START, "baseStartTask start")
+        initXLog()
+        initAPMService(APMConfig())
+        initAPM(this@App)
+        initStat { StatConfig() }
+        installCrashProtector(CrashConfig())
+        initCrash(this@App) //依赖xlog,stat,crash protector
+        AAB.init(AABConfig())
+        initJsonConfig(JsonConfig())
+        Log.i(TAG_TIME_APP_START, "baseStartTask end, cost: ${SystemClock.elapsedRealtime() - startTs}")
+    }
+
+    private fun initXLog() {
+        XLogHelper.initXLog(
+            if (BuildConfig.OFFICIAL || BuildConfig.DEBUG) Xlog.LEVEL_ALL else Xlog.LEVEL_INFO,
+            FilePath.logPath,
+            FilePath.logPath,
+            BuildConfig.DEBUG
+        )
+        Log.setLogConfig(LogConfig())
+    }
 
+    /**
+     * APP初始化任务(阻塞主线程)
+     */
+    inner class InitPush : MainThreadStartUpTask() {
         override fun run() {
-            initXLog()
-            initAPMService(APMConfig())
-            initAPM(this@App)
-            initStat { StatConfig() }
-            installCrashProtector(CrashConfig())
-            initCrash(this@App) //依赖xlog,stat,crash protector
-            AAB.init(AABConfig())
+            pushService.init(PushServiceConfig())
+            NotificationUtil.createNotificationChannel(getCompatString(R.string.channel_event))
         }
     }
 
-    inner class SecondStartTask : MainThreadStartTask() {
+    inner class InitUI : MainThreadStartUpTask() {
         override fun run() {
-            initJsonConfig(JsonConfig())
-            initPush()
             //UI初始化
             WEUI.init(this@App)
-            initTCEffect()
-            initSVGA()
-            initAutoSize()
-            imageService.init(ImageConfig())
-            OperationModule.init()
+            ScreenAutoSizeUtil.init(this@App, !AppBaseInfo.isRelease)
+            WindowManagerProxy.init()
         }
     }
 
+    inner class InitImageService : MainThreadStartUpTask() {
+        override fun run() {
+            imageService.init(ImageConfig())
+        }
 
-    abstract inner class SubWaitStartTask : AppStartTask() {
-        override val isRunOnMainThread: Boolean = false
+        override val dependsTaskList: List<Class<out StartUpTask>>
+            get() = listOf(InitUI::class.java)
+    }
 
-        override fun needWait(): Boolean {
-            return true
+    inner class InitTCEffect : SubWaitStartUpTask() {
+        override fun run() {
+            TCEffectManager.init(TCEffectConfig())
         }
 
-        override val dependsTaskList: List<Class<out AppStartTask>>
-            get() = listOf(BaseStartTask::class.java)
+        override val dependsTaskList: List<Class<out StartUpTask>>
+            get() = listOf(InitUI::class.java)
     }
 
-    /**
-     * 子启动任务(不需要等待完成)
-     */
-    abstract inner class SubNoWaitStartTask : AppStartTask() {
-        override val isRunOnMainThread: Boolean = false
-
-        override fun needWait(): Boolean {
-            return false
+    inner class InitSVGA : SubWaitStartUpTask() {
+        override fun run() {
+            SVGAManager.init(this@App, SVGA_CONFIG)
         }
 
-        override val dependsTaskList: List<Class<out AppStartTask>>
-            get() = listOf(BaseStartTask::class.java)
+        override val dependsTaskList: List<Class<out StartUpTask>>
+            get() = listOf(InitUI::class.java)
     }
 
-
-    /**
-     * 轻量任务1(每一项任务耗时控制在100ms内)
-     * (耗时可通过trace导出)
-     */
-    inner class LightWaitTask1 : SubWaitStartTask() {
+    inner class InitRouter : SubWaitStartUpTask() {
         override fun run() {
             Router.config = RouterConfig()
             deeplinkRouterManager.init(DeepLinkConfig())
+        }
+    }
+
+    inner class InitLanguage : SubWaitStartUpTask() {
+        override fun run() {
             languageManager.init()
+        }
+    }
+
+    inner class InitSecurityService : SubWaitStartUpTask() {
+        override fun run() {
             securityService.init()
+        }
+    }
+
+    inner class InitGoogleService : SubWaitStartUpTask() {
+        override fun run() {
             googleService.init()
-            registerNetworkReceiver()
+        }
+    }
+
+    inner class InitStorageService : SubWaitStartUpTask() {
+        override fun run() {
             initStorageService(StorageConfig())
+        }
+    }
+
+    inner class InitShareManager : SubWaitStartUpTask() {
+        override fun run() {
             initShareManager(ShareConfig())
+        }
+    }
+
+    inner class InitOssService : SubWaitStartUpTask() {
+        override fun run() {
             initOssService { ossService }
+        }
+    }
+
+    inner class InitJSBridgeManager : SubWaitStartUpTask() {
+        override fun run() {
             initJSBridgeManager { jsBridgeManager }
+        }
+    }
+
+    inner class InitWebResourceLoader : SubWaitStartUpTask() {
+        override fun run() {
             initWebResourceLoader(WebResourceConfig())
+        }
+
+        override val dependsTaskList: List<Class<out StartUpTask>>
+            get() = listOf(InitNetwork::class.java)
+    }
+
+    inner class InitDownloadService : SubWaitStartUpTask() {
+        override fun run() {
             initDownloadService { downloadService }
+        }
+
+        override val dependsTaskList: List<Class<out StartUpTask>>
+            get() = listOf(InitNetwork::class.java)
+    }
+
+    inner class InitEffect : SubWaitStartUpTask() {
+        override fun run() {
             initEffect { effect }
-            WindowManagerProxy.init()
         }
     }
 
-    inner class LightWaitTask2 : SubWaitStartTask() {
+    inner class InitFirebaseAnalytics : SubWaitStartUpTask() {
         override fun run() {
-            initFirebaseAnalytics()
-            initFB()
-            initPayerMax()
+            val analytics = FirebaseAnalytics.getInstance(applicationContext)
+            analytics.setUserProperty(ALLOW_AD_PERSONALIZATION_SIGNALS, "true")
+            analytics.setAnalyticsCollectionEnabled(true)
         }
     }
 
-    inner class LightNoWaitTask1 : SubNoWaitStartTask() {
+    inner class InitFB : SubWaitStartUpTask() {
         override fun run() {
-            initAttribution()
-            deviceIdService.updateDeviceId()
-            networkService.fetchNetAntiBanConfig()
-            urlConfigService.init()
-            soundPlayer.prepare()
+            if (!AppBaseInfo.isRelease) {
+                FacebookSdk.setIsDebugEnabled(AppBaseInfo.isRelease)
+                FacebookSdk.addLoggingBehavior(LoggingBehavior.APP_EVENTS)
+            }
         }
     }
 
+    inner class InitPayerMax : SubWaitStartUpTask() {
+        override fun run() {
+            PayerMaxHelper.init(this@App)
+        }
+    }
 
-    /**
-     * 重任务(任务耗时>30ms)
-     */
-    inner class InitNetwork : SubWaitStartTask() {
+    inner class InitNetwork : SubWaitStartUpTask() {
         override fun run() {
             networkManager.init(this@App)
+            registerNetworkReceiver()
         }
     }
 
-    inner class InitIM : SubWaitStartTask() {
+    inner class InitIM : SubWaitStartUpTask() {
         override fun run() {
             imService.init(
                 this@App,
@@ -311,7 +408,7 @@ class App : SplitCompatApplication(), ActivityLifecycleCallbacksExt {
     }
 
     //1v1呼叫主线程
-    inner class InitCall1 : SubWaitStartTask() {
+    inner class InitCall1 : SubWaitStartUpTask() {
         override val isRunOnMainThread: Boolean = true
 
         override fun run() {
@@ -320,194 +417,68 @@ class App : SplitCompatApplication(), ActivityLifecycleCallbacksExt {
     }
 
     //1v1呼叫子线程
-    inner class InitCall2 : SubWaitStartTask() {
+    inner class InitCall2 : SubWaitStartUpTask() {
         override fun run() {
             CallModule.appOnCreateSubTask(this@App)
         }
 
-        override val dependsTaskList: List<Class<out AppStartTask>>
+        override val dependsTaskList: List<Class<out StartUpTask>>
             get() = listOf(
                 *super.dependsTaskList.toTypedArray(),
                 InitCall1::class.java
             )
     }
 
-    inner class InitTCTuringManager : SubWaitStartTask() {
+    inner class InitTCTuringManager : SubWaitStartUpTask() {
         override fun run() {
             TCTuringManager.init(TCTuringConfig())
         }
     }
 
-
-    inner class InitDebugKit : SubWaitStartTask() {
+    inner class InitDebugKit : SubWaitStartUpTask() {
         override val isRunOnMainThread: Boolean = true
 
         override fun run() {
-            initDebugKit()
-        }
-    }
-
-    override fun onCreate() {
-        super.onCreate()
-        val appOnCreateTs = SystemClock.elapsedRealtime()
-        android.util.Log.d(TAG_TIME_APP_START, "app onCreate start")
-
-        AppStartTaskDispatcher.create().apply {
-            //基础任务(主线程)
-            addAppStartTask(BaseStartTask())
-            addAppStartTask(SecondStartTask())
-
-            //轻量任务(子线程并行, 占用主流程初始化时间)
-            addAppStartTask(LightWaitTask1())
-            addAppStartTask(LightWaitTask2())
-
-            //轻量任务(子线程并行, 占用主流程初始化时间)
-            addAppStartTask(InitNetwork())
-            addAppStartTask(InitTCTuringManager())
-            addAppStartTask(InitIM())
-            addAppStartTask(InitCall1())
-            addAppStartTask(InitCall2())
-
-            //其他子任务(不卡主流程)
-            addAppStartTask(LightNoWaitTask1())
-            if (!AppBaseInfo.isRelease) {
-                addAppStartTask(InitDebugKit())
+            if (AppBaseInfo.isRelease) {
+                return
             }
-
-        }.start().await()
-
-        android.util.Log.d(TAG_TIME_APP_START, "app onCreate end, cost:${SystemClock.elapsedRealtime() - appOnCreateTs}")
-    }
-
-    private fun initXLog() {
-        XLogHelper.initXLog(
-            if (BuildConfig.OFFICIAL || BuildConfig.DEBUG) Xlog.LEVEL_ALL else Xlog.LEVEL_INFO,
-            FilePath.logPath,
-            FilePath.logPath,
-            BuildConfig.DEBUG
-        )
-        Log.setLogConfig(LogConfig())
-    }
-
-    private fun initTCEffect() {
-        TCEffectManager.init(TCEffectConfig())
-    }
-
-    private fun initSVGA() {
-        val config = SvgaConfig(
-            diskCacheParamsSupplier = object : DiskCacheParamsSupplier {
-                override fun getPath(): File = File(applicationContext.cacheDir, "svga")
-
-                override fun getDiskTrimStrategy(): DiskTrimStrategy {
-                    return object : DiskTrimStrategy {
-                        override fun maxSize(): Long = ByteConstants.MB * 100L
-                        override fun timeExpired(): Long = TimeUnit.DAYS.toMillis(10)
+            if (DebugPrefs.showPerformanceFloatView) {
+                floatKitManager.install(this@App, true)
+                floatKitManager.onMainIconDoubleClick = {
+                    AppUtil.currentActivity?.let {
+                        Router.build(it, Debug.Debug.PATH).start()
                     }
                 }
-            },
-            executorsSupplier = object : ExecutorsSupplier {
-
-                override fun getBackgroundExecutor(): Executor {
-                    return Dispatcher.wenextThreadPoolExecutor
-                }
-
-                override fun getIOExecutor(): Executor {
-                    return Dispatcher.wenextThreadPoolExecutor
-                }
-
-                override fun getNetWorkExecutor(): Executor {
-                    return Dispatcher.wenextThreadPoolExecutor
+                performanceDataController.start()
+            }
+            TooLargeTool.startLogging(this@App, DefaultFormatter(), object : Logger {
+                override fun log(msg: String) {
+                    Log.i(TAG_TOO_LARGE_TOOL, msg)
                 }
 
-            },
-            debuggable = !AppBaseInfo.isRelease,
-            imageFetcher = object : ImageFetcher {
-
-                override fun fetchDynamicImage(
-                    url: String,
-                    forKey: String,
-                    callback: ImageFetchCallback?
-                ) {
-                    imageService.fetchImage(url, object : IImageLoadResultListener {
-                        override fun onSuccess(bitmap: Bitmap) {
-                            super.onSuccess(bitmap)
-                            callback?.onFetched(bitmap, forKey)
-                        }
-
-                        override fun onFailed() {
-                            super.onFailed()
-                            callback?.onFailure(Exception("load image failed"), forKey)
-                        }
-
-                        override fun onCancel() {
-                            super.onCancel()
-                            callback?.onFailure(Exception("load image canceled"), forKey)
-                        }
-                    })
+                override fun logException(e: Exception) {
+                    Log.e(TAG_TOO_LARGE_TOOL, "logException", e)
                 }
-
-            },
-            designWidthPx = 750f,
-            enableSvgaChecker = !AppBaseInfo.isRelease && DebugPrefs.enableSvgaChecker,
-            enableShowSvgaCheckResult = !AppBaseInfo.isRelease && DebugPrefs.enableSvgaChecker && DebugPrefs.enableShowSvgaCheckResult
-        )
-        SVGAManager.init(applicationContext, config)
-    }
-
-    private fun initFirebaseAnalytics() {
-        val analytics = FirebaseAnalytics.getInstance(applicationContext)
-        analytics.setUserProperty(ALLOW_AD_PERSONALIZATION_SIGNALS, "true")
-        analytics.setAnalyticsCollectionEnabled(true)
-    }
-
-    private fun initAttribution() {
-        AttributionModule.initialize()
-        AttributionModule.start()
-        AttributionModule.reportFirstOpen()
-    }
-
-    private fun initFB() {
-        if (!AppBaseInfo.isRelease) {
-            FacebookSdk.setIsDebugEnabled(AppBaseInfo.isRelease)
-            FacebookSdk.addLoggingBehavior(LoggingBehavior.APP_EVENTS)
+            })
         }
     }
 
-    private fun initPush() {
-        pushService.init(PushServiceConfig())
-        NotificationUtil.createNotificationChannel(getCompatString(R.string.channel_event))
-    }
-
-    private fun initPayerMax() {
-        PayerMaxHelper.init(this)
-    }
+    /**
+     * 其他任务(非阻塞主线程)
+     */
+    inner class InitOther : SubNoWaitStartUpTask() {
+        override fun run() {
+            deviceIdService.updateDeviceId()
+            networkService.fetchNetAntiBanConfig()
+            urlConfigService.init()
+            soundPlayer.prepare()
 
-    private fun initAutoSize() {
-        ScreenAutoSizeUtil.init(this, !AppBaseInfo.isRelease)
-    }
+            AttributionModule.initialize()
+            AttributionModule.start()
+            AttributionModule.reportFirstOpen()
 
-    private fun initDebugKit() {
-        if (AppBaseInfo.isRelease) {
-            return
-        }
-        if (DebugPrefs.showPerformanceFloatView) {
-            floatKitManager.install(this, true)
-            floatKitManager.onMainIconDoubleClick = {
-                AppUtil.currentActivity?.let {
-                    Router.build(it, Debug.Debug.PATH).start()
-                }
-            }
-            performanceDataController.start()
+            OperationModule.init()
         }
-        TooLargeTool.startLogging(this, DefaultFormatter(), object : Logger {
-            override fun log(msg: String) {
-                Log.i(TAG_TOO_LARGE_TOOL, msg)
-            }
-
-            override fun logException(e: Exception) {
-                Log.e(TAG_TOO_LARGE_TOOL, "logException", e)
-            }
-        })
     }
 
     override fun onTerminate() {

+ 37 - 0
app/src/main/java/com/adealink/weparty/AppStartTask.kt

@@ -0,0 +1,37 @@
+package com.adealink.weparty
+
+import com.adealink.frame.startup.task.StartUpTask
+
+
+/**
+ * 主线程启动任务(需要等待完成)
+ */
+abstract class MainThreadStartUpTask : StartUpTask() {
+    override val isRunOnMainThread: Boolean = true
+
+    override fun needWait(): Boolean {
+        return true
+    }
+}
+
+/**
+ * 子启动任务(需要等待完成)
+ */
+abstract class SubWaitStartUpTask : StartUpTask() {
+    override val isRunOnMainThread: Boolean = false
+
+    override fun needWait(): Boolean {
+        return true
+    }
+}
+
+/**
+ * 子启动任务(不需要等待完成)
+ */
+abstract class SubNoWaitStartUpTask : StartUpTask() {
+    override val isRunOnMainThread: Boolean = false
+
+    override fun needWait(): Boolean {
+        return false
+    }
+}

+ 77 - 0
app/src/main/java/com/adealink/weparty/effect/SvgaConfig.kt

@@ -0,0 +1,77 @@
+package com.adealink.weparty.effect
+
+import android.graphics.Bitmap
+import com.adealink.frame.base.AppBaseInfo
+import com.adealink.frame.coroutine.dispatcher.Dispatcher
+import com.adealink.frame.image.imageService
+import com.adealink.frame.image.listener.IImageLoadResultListener
+import com.adealink.frame.util.AppUtil
+import com.adealink.weparty.debug.DebugPrefs
+import com.opensource.svgaplayer.control.SvgaConfig
+import com.opensource.svgaplayer.disk.DiskCacheParamsSupplier
+import com.opensource.svgaplayer.disk.DiskTrimStrategy
+import com.opensource.svgaplayer.executor.ExecutorsSupplier
+import com.opensource.svgaplayer.remote.ImageFetchCallback
+import com.opensource.svgaplayer.remote.ImageFetcher
+import com.opensource.svgaplayer.utils.ByteConstants
+import java.io.File
+import java.util.concurrent.Executor
+import java.util.concurrent.TimeUnit
+
+val SVGA_CONFIG = SvgaConfig(
+    diskCacheParamsSupplier = object : DiskCacheParamsSupplier {
+        override fun getPath(): File = File(AppUtil.appContext.cacheDir, "svga")
+
+        override fun getDiskTrimStrategy(): DiskTrimStrategy {
+            return object : DiskTrimStrategy {
+                override fun maxSize(): Long = ByteConstants.MB * 100L
+                override fun timeExpired(): Long = TimeUnit.DAYS.toMillis(10)
+            }
+        }
+    },
+    executorsSupplier = object : ExecutorsSupplier {
+
+        override fun getBackgroundExecutor(): Executor {
+            return Dispatcher.wenextThreadPoolExecutor
+        }
+
+        override fun getIOExecutor(): Executor {
+            return Dispatcher.wenextThreadPoolExecutor
+        }
+
+        override fun getNetWorkExecutor(): Executor {
+            return Dispatcher.wenextThreadPoolExecutor
+        }
+
+    },
+    debuggable = !AppBaseInfo.isRelease,
+    imageFetcher = object : ImageFetcher {
+
+        override fun fetchDynamicImage(
+            url: String,
+            forKey: String,
+            callback: ImageFetchCallback?
+        ) {
+            imageService.fetchImage(url, object : IImageLoadResultListener {
+                override fun onSuccess(bitmap: Bitmap) {
+                    super.onSuccess(bitmap)
+                    callback?.onFetched(bitmap, forKey)
+                }
+
+                override fun onFailed() {
+                    super.onFailed()
+                    callback?.onFailure(Exception("load image failed"), forKey)
+                }
+
+                override fun onCancel() {
+                    super.onCancel()
+                    callback?.onFailure(Exception("load image canceled"), forKey)
+                }
+            })
+        }
+
+    },
+    designWidthPx = 750f,
+    enableSvgaChecker = !AppBaseInfo.isRelease && DebugPrefs.enableSvgaChecker,
+    enableShowSvgaCheckResult = !AppBaseInfo.isRelease && DebugPrefs.enableSvgaChecker && DebugPrefs.enableShowSvgaCheckResult
+)

+ 2 - 2
app/src/main/java/com/adealink/weparty/module/call/ICallService.kt

@@ -3,14 +3,14 @@ package com.adealink.weparty.module.call
 import androidx.lifecycle.ViewModelStoreOwner
 import com.adealink.frame.aab.IService
 import com.adealink.frame.media.IMediaOperatorGet
-import com.adealink.frame.startup.IStartUpTask
+import com.adealink.frame.startup.IAppStartUpTask
 import com.adealink.weparty.commonui.widget.floatview.data.IFloatData
 import com.adealink.weparty.commonui.widget.floatview.view.BaseFloatView
 import com.adealink.weparty.module.call.data.CallerSource
 import com.adealink.weparty.module.call.data.MediaType
 import com.adealink.weparty.module.call.viewmodel.ICallViewModel
 
-interface ICallService : IService<ICallService>, IMediaOperatorGet, IStartUpTask {
+interface ICallService : IService<ICallService>, IMediaOperatorGet, IAppStartUpTask {
 
     fun call(
         uid: Long,

+ 2 - 2
app/src/main/java/com/adealink/weparty/module/message/IMessageService.kt

@@ -4,7 +4,7 @@ import androidx.lifecycle.ViewModelStoreOwner
 import com.adealink.frame.aab.IService
 import com.adealink.frame.base.Rlt
 import com.adealink.frame.imkit.manager.UnReadMessageManager
-import com.adealink.frame.startup.IStartUpTask
+import com.adealink.frame.startup.IAppStartUpTask
 import com.adealink.weparty.commonui.widget.floatview.data.IFloatData
 import com.adealink.weparty.commonui.widget.floatview.view.BaseFloatView
 import com.adealink.weparty.module.message.data.CustomerInfo
@@ -13,7 +13,7 @@ import com.adealink.weparty.module.profile.data.UserFamilySetting
 import io.rong.imlib.IRongCoreCallback
 import io.rong.imlib.model.Conversation
 
-interface IMessageService : IService<IMessageService>, IStartUpTask {
+interface IMessageService : IService<IMessageService>, IAppStartUpTask {
     fun getMessageViewModel(owner: ViewModelStoreOwner): IMessageViewModel?
 
     /**

+ 44 - 46
app/src/main/java/com/adealink/weparty/ui/MainStartUpFragment.kt

@@ -3,18 +3,16 @@ package com.adealink.weparty.ui
 import android.os.Bundle
 import android.os.SystemClock
 import androidx.core.app.NotificationManagerCompat
+import androidx.lifecycle.lifecycleScope
 import com.adealink.frame.base.fastLazy
+import com.adealink.frame.coroutine.dispatcher.Dispatcher
 import com.adealink.frame.log.Log
 import com.adealink.frame.push.manager.pushService
-import com.adealink.frame.startup.executor.TaskExecutorManager
 import com.adealink.frame.statistics.BaseStatEvent
 import com.adealink.frame.util.AppUtil
-import com.adealink.frame.util.removeUiCallbacks
-import com.adealink.frame.util.runOnUiThread
 import com.adealink.weparty.BuildConfig
 import com.adealink.weparty.commonui.BaseActivity
 import com.adealink.weparty.commonui.BaseFragment
-import com.adealink.weparty.commonui.ext.isUiValid
 import com.adealink.weparty.config.globalConfigManager
 import com.adealink.weparty.log.manager.logManager
 import com.adealink.weparty.module.account.AccountModule
@@ -47,6 +45,9 @@ import com.adealink.weparty.webview.manager.PreloadWebViewWorker
 import com.google.firebase.crashlytics.ktx.crashlytics
 import com.google.firebase.crashlytics.ktx.setCustomKeys
 import com.google.firebase.ktx.Firebase
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 
 /**
  * 主界面初始化
@@ -59,15 +60,15 @@ class MainStartUpFragment : BaseFragment() {
     private val walletViewModel by fastLazy { WalletModule.getWalletViewModel(requireActivity()) }
     private val anchorViewModel by fastLazy { AnchorModule.getAnchorViewModel(requireActivity()) }
 
-    private val importantTask by fastLazy {
-        Runnable {
-            TaskExecutorManager.instance.subThreadPoolExecutor.execute {
-                importantLoad()
-            }
+    private suspend fun importantTask() {
+        withContext(Dispatcher.WENEXT_THREAD_POOL) {
+            importantLoad()
         }
     }
 
     private fun importantLoad() {
+        val startTs = SystemClock.elapsedRealtime()
+        Log.d(TAG, "importantLoad-start")
         if (AccountModule.isLogin()) {
             AccountModule.checkRemoteVirtualAppConfig()
             AttributionModule.reportAttributionData()
@@ -93,43 +94,44 @@ class MainStartUpFragment : BaseFragment() {
         RoomModule.init()
 //        GameModule.checkPlayingGame()
 
-        //先这样搞吧,避免崩溃
-        runIfUiValid { roomAttrViewModel?.getMyRoomInfo(true) }
-        runIfUiValid { countryViewModel?.getCountryList(true) }
-        runIfUiValid { walletViewModel?.checkThirdPayOpen() }
-        runIfUiValid { anchorViewModel?.getAnchorMessages() }
+        roomAttrViewModel?.getMyRoomInfo(true)
+        countryViewModel?.getCountryList(true)
+        walletViewModel?.checkThirdPayOpen()
+        anchorViewModel?.getAnchorMessages()
+        Log.d(TAG, "importantLoad-end, cost:${SystemClock.elapsedRealtime() - startTs}ms")
     }
 
-    private val minorTask by fastLazy {
-        Runnable {
-            TaskExecutorManager.instance.subThreadPoolExecutor.execute {
-                minorLoad()
-            }
+    private suspend fun minorTask() {
+        withContext(Dispatcher.WENEXT_THREAD_POOL) {
+            minorLoad()
         }
     }
 
     private fun minorLoad() {
+        val startTs = SystemClock.elapsedRealtime()
+        Log.d(TAG, "minorLoad-start")
         WalletModule.fetchCurrency()
         WalletModule.queryAndHandleUnDealPurchases()
         LevelModule.pullLevelConfigs()
         CoupleModule.pullCoupleConfig()
         WalletModule.init()
         ProfileModule.pullUserNoteNameData()
-        runIfUiValid {  walletViewModel?.addGlobalConfigListener() }
-        runIfUiValid {  walletViewModel?.getUserChargeNotify() }
+        walletViewModel?.addGlobalConfigListener()
+        walletViewModel?.getUserChargeNotify()
         globalConfigManager.getAllGlobalConfig(true)
         GameModule.initRocket()
+        Log.d(TAG, "minorLoad-end, cost:${SystemClock.elapsedRealtime() - startTs}ms")
     }
 
-    private val otherTask by fastLazy {
-        Runnable {
-            TaskExecutorManager.instance.subThreadPoolExecutor.execute {
-                otherLoad()
-            }
+    private suspend fun otherTask() {
+        withContext(Dispatcher.WENEXT_THREAD_POOL) {
+            otherLoad()
         }
     }
 
     private fun otherLoad() {
+        val startTs = SystemClock.elapsedRealtime()
+        Log.d(TAG, "otherLoad-start")
         GiftModule.getGifts(true)
         EmotionModule.getEmotionPackages(true)
         MedalModule.init()
@@ -141,15 +143,13 @@ class MainStartUpFragment : BaseFragment() {
         RoomTaskMonitor.init()
         HeadlineModule.init()
         OperationModule.checkSuperSupporterWhatsAppFillStatus()
-        runIfUiValid {
-            familyInfoViewModel?.getApplyJoinFamilyUnHandleNum()
-        }
+        familyInfoViewModel?.getApplyJoinFamilyUnHandleNum()
         reportPushSwitch()
+        Log.d(TAG, "otherLoad-end, cost:${SystemClock.elapsedRealtime() - startTs}ms")
     }
 
     private fun reportPushSwitch() {
-        val activity = activity ?: return
-        val manager: NotificationManagerCompat = NotificationManagerCompat.from(activity)
+        val manager: NotificationManagerCompat = NotificationManagerCompat.from(requireActivity())
         val isOpen = manager.areNotificationsEnabled()
         PushStatEvent(PushStatEvent.Action.SWITCH).apply {
             switch to if (isOpen) 1 else 0
@@ -158,20 +158,24 @@ class MainStartUpFragment : BaseFragment() {
 
     override fun onActivityCreated(savedInstanceState: Bundle?) {
         super.onActivityCreated(savedInstanceState)
-        val startTs = SystemClock.elapsedRealtime()
-        Log.i(TAG, "StartUpFragment.onCreate() start")
-        runOnUiThread(importantTask)
-        runOnUiThread(minorTask, 2000L)
-        runOnUiThread(otherTask, 3000L)
-        Log.i(TAG, "StartUpFragment.onCreate() end, cost: ${SystemClock.elapsedRealtime() - startTs}")
+        Log.i(TAG, "StartUpFragment.onCreate()")
+        lifecycleScope.launch {
+            importantTask()
+        }
+        lifecycleScope.launch {
+            delay(2000L)
+            minorTask()
+        }
+        lifecycleScope.launch {
+            delay(3000L)
+            otherTask()
+        }
     }
 
     override fun onDestroy() {
         super.onDestroy()
+        Log.i(TAG, "StartUpFragment.onDestroy()")
         PreloadWebViewManager.destroy()
-        removeUiCallbacks(importantTask)
-        removeUiCallbacks(minorTask)
-        removeUiCallbacks(otherTask)
     }
 
     companion object {
@@ -187,10 +191,4 @@ class MainStartUpFragment : BaseFragment() {
         }
     }
 
-    /**
-     * 要注意:MainStartUpFragment 是一个没有view的fragment
-     */
-    fun runIfUiValid(block: () -> Unit) {
-        if (activity?.isUiValid() == true) block()
-    }
 }

+ 4 - 1
frame/startup/proguard-rules.pro

@@ -18,4 +18,7 @@
 
 # If you keep the line number information, uncomment this to
 # hide the original source file name.
-#-renamesourcefileattribute SourceFile
+#-renamesourcefileattribute SourceFile
+
+#Start Up
+-keep public class * extends com.adealink.frame.startup.task.StartUpTask

+ 1 - 1
frame/startup/src/main/java/com/adealink/frame/startup/IStartUpTask.kt → frame/startup/src/main/java/com/adealink/frame/startup/IAppStartUpTask.kt

@@ -2,7 +2,7 @@ package com.adealink.frame.startup
 
 import android.app.Application
 
-interface IStartUpTask {
+interface IAppStartUpTask {
     /**
      * 应用启动(主线程任务)
      */

+ 2 - 2
frame/startup/src/main/java/com/adealink/frame/startup/base/TaskInterface.kt

@@ -2,7 +2,7 @@ package com.adealink.frame.startup.base
 
 import android.os.Process
 import androidx.annotation.IntRange
-import com.adealink.frame.startup.task.AppStartTask
+import com.adealink.frame.startup.task.StartUpTask
 import java.util.concurrent.Executor
 
 interface TaskInterface {
@@ -14,7 +14,7 @@ interface TaskInterface {
     fun runOnExecutor(): Executor
 
     //所依赖的父亲们,父亲们执行完了,孩子才能执行
-    val dependsTaskList: List<Class<out AppStartTask>>
+    val dependsTaskList: List<Class<out StartUpTask>>
 
     //在非主线程执行的Task是否需要在被调用await的时候等待,默认不需要,返回true即在Application的onCreate中阻塞,直到该任务执行完
     fun needWait(): Boolean

+ 90 - 40
frame/startup/src/main/java/com/adealink/frame/startup/dispatcher/AppStartTaskDispatcher.kt → frame/startup/src/main/java/com/adealink/frame/startup/dispatcher/StartTaskDispatcher.kt

@@ -1,34 +1,41 @@
 package com.adealink.frame.startup.dispatcher
 
 import android.os.Looper
-import android.util.Log
 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.runnable.AppStartTaskRunnable
-import com.adealink.frame.startup.task.AppStartTask
-import com.adealink.frame.startup.util.AppStartTaskSortUtil.getSortResult
+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 AppStartTaskDispatcher private constructor() {
+class StartTaskDispatcher private constructor() {
     //存放每个Task  (key= Class < ? extends AppStartTask>)
-    private val mTaskHashMap = HashMap<Class<out AppStartTask>, AppStartTask>()
+    private val mTaskHashMap = HashMap<Class<out StartUpTask>, StartUpTask>()
 
     //每个Task的孩子 (key= Class < ? extends AppStartTask>)
-    private val mTaskChildHashMap = HashMap<Class<out AppStartTask>, MutableList<Class<out AppStartTask>>>()
+    private val mTaskChildHashMap = HashMap<Class<out StartUpTask>, MutableList<Class<out StartUpTask>>>()
 
     //通过Add添加进来的所有任务
-    private val mStartTaskList: MutableList<AppStartTask> = ArrayList()
+    private val mStartTaskList: MutableList<StartUpTask> = ArrayList()
 
     //拓扑排序后的所有任务
-    private var mSortTaskList: List<AppStartTask>? = null
+    private var mSortTaskList: List<StartUpTask>? = null
 
     //拓扑排序后的主线程的任务
-    private val mSortMainThreadTaskList: MutableList<AppStartTask> = ArrayList()
+    private val mSortMainThreadTaskList: MutableList<StartUpTask> = ArrayList()
+    private val mMainThreadTaskCount = AtomicInteger()
 
     //拓扑排序后的子线程的任务
-    private val mSortThreadPoolTaskList: MutableList<AppStartTask> = ArrayList()
+    private val mSortThreadPoolTaskList: MutableList<StartUpTask> = ArrayList()
+
+    //待执行的任务
+    private val mPendingTaskList: LinkedBlockingQueue<StartUpTask> = LinkedBlockingQueue()
 
     //需要等待的任务总数,用于阻塞
     private var mCountDownLatch: CountDownLatch? = null
@@ -39,29 +46,30 @@ class AppStartTaskDispatcher private constructor() {
     //所有的任务开始时间,结束时间
     private var mStartTime: Long = 0
     private var mFinishTime: Long = 0
+    private var mAllTaskTime: Long = 0
 
     //所有阻塞任务的总超时时间
     private var mAllTaskWaitTimeOut = WAITING_TIME
 
-    fun setAllTaskWaitTimeOut(allTaskWaitTimeOut: Long): AppStartTaskDispatcher {
+    fun setAllTaskWaitTimeOut(allTaskWaitTimeOut: Long): StartTaskDispatcher {
         mAllTaskWaitTimeOut = allTaskWaitTimeOut
         return this
     }
 
-    fun addAppStartTask(appStartTask: AppStartTask?): AppStartTaskDispatcher {
-        if (appStartTask == null) {
+    fun addAppStartTask(startUpTask: StartUpTask?): StartTaskDispatcher {
+        if (startUpTask == null) {
             throw RuntimeException("addAppStartTask() 传入的appStartTask为null")
         }
-        mStartTaskList.add(appStartTask)
-        if (ifNeedWait(appStartTask)) {
+        mStartTaskList.add(startUpTask)
+        if (ifNeedWait(startUpTask)) {
             mNeedWaitCount.getAndIncrement()
         }
         return this
     }
 
-    fun start(): AppStartTaskDispatcher {
+    fun start(): StartTaskDispatcher {
         if (Looper.getMainLooper() != Looper.myLooper()) {
-            throw RuntimeException("start方法必须在主线程调用")
+            throw RuntimeException("start() must called on MainThread")
         }
         mStartTime = System.currentTimeMillis()
         //拓扑排序,拿到排好序之后的任务队列
@@ -70,7 +78,7 @@ class AppStartTaskDispatcher private constructor() {
         printSortTask()
         mCountDownLatch = CountDownLatch(mNeedWaitCount.get())
 
-        Log.d(TAG_START_UP, "start(), mStartTime:$mStartTime, mNeedWaitCount:${mNeedWaitCount.get()}")
+        Log.i(TAG_START_UP, "start(), mStartTime:$mStartTime, mNeedWaitCount:${mNeedWaitCount.get()}")
         dispatchAppStartTask()
         return this
     }
@@ -84,6 +92,7 @@ class AppStartTaskDispatcher private constructor() {
         for (appStartTask in sortTaskList) {
             if (appStartTask.isRunOnMainThread) {
                 mSortMainThreadTaskList.add(appStartTask)
+                mMainThreadTaskCount.getAndIncrement()
             } else {
                 mSortThreadPoolTaskList.add(appStartTask)
             }
@@ -92,11 +101,11 @@ class AppStartTaskDispatcher private constructor() {
 
     //输出排好序的Task
     private fun printSortTask() {
-        if(AppBaseInfo.isRelease){
-           return
+        if (AppBaseInfo.isRelease) {
+            return
         }
         val sb = StringBuilder()
-        sb.append("当前所有任务排好的顺序为:")
+        sb.append("printSortedTask():")
         val sortTaskList = mSortTaskList ?: emptyList()
         for (i in sortTaskList.indices) {
             val taskName = sortTaskList[i].javaClass.simpleName
@@ -108,7 +117,7 @@ class AppStartTaskDispatcher private constructor() {
         Log.i(TAG_START_UP, sb.toString())
 
         val mainTaskSb = StringBuilder()
-        mainTaskSb.append("    主线程任务顺序: ")
+        mainTaskSb.append("    MainThread Task List: ")
         for (i in mSortMainThreadTaskList.indices) {
             val taskName = mSortMainThreadTaskList[i].javaClass.simpleName
             if (i != 0) {
@@ -119,7 +128,7 @@ class AppStartTaskDispatcher private constructor() {
         Log.i(TAG_START_UP, mainTaskSb.toString())
 
         val threadTaskSb = StringBuilder()
-        threadTaskSb.append("    子线程任务顺序: ")
+        threadTaskSb.append("    SubThread Task List: ")
         for (i in mSortThreadPoolTaskList.indices) {
             val taskName = mSortThreadPoolTaskList[i].javaClass.simpleName
             if (i != 0) {
@@ -128,25 +137,38 @@ class AppStartTaskDispatcher private constructor() {
             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) {
-            appStartTask.runOnExecutor().execute(AppStartTaskRunnable(appStartTask, this))
+            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) {
-            AppStartTaskRunnable(appStartTask, this).run()
+            StartTaskRunnable(appStartTask, this).run()
         }
     }
 
     //通知Children一个前置任务已完成
-    fun setNotifyChildren(appStartTask: AppStartTask) {
-        val arrayList = mTaskChildHashMap[appStartTask.javaClass]
+    fun setNotifyChildren(startUpTask: StartUpTask) {
+        val arrayList = mTaskChildHashMap[startUpTask.javaClass]
         if (arrayList != null && arrayList.size > 0) {
             for (aclass in arrayList) {
                 mTaskHashMap[aclass]?.notifyDependFinish()
@@ -155,28 +177,56 @@ class AppStartTaskDispatcher private constructor() {
     }
 
     //标记已经完成的Task
-    fun markAppStartTaskFinish(appStartTask: AppStartTask) {
-        if (ifNeedWait(appStartTask)) {
+    fun markAppStartTaskFinish(startUpTask: StartUpTask, taskCostTime: Long) {
+        if (ifNeedWait(startUpTask)) {
             mCountDownLatch?.countDown()
             mNeedWaitCount.getAndDecrement()
         }
-        Log.i(TAG_START_UP, "markAppStartTaskFinish, ${appStartTask.javaClass.simpleName}, mNeedWaitCount:${mNeedWaitCount.get()}")
+        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: AppStartTask): Boolean {
-        return !task.isRunOnMainThread && task.needWait()
+    private fun ifNeedWait(task: StartUpTask): Boolean {
+        return task.isRunOnMainThread || task.needWait()
     }
 
     //等待,阻塞主线程
     fun await() {
         try {
-            val countDownLatch = mCountDownLatch ?: throw RuntimeException("在调用await()之前,必须先调用start()")
+            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, "启动耗时:$mFinishTime")
+            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()
         }
@@ -185,8 +235,8 @@ class AppStartTaskDispatcher private constructor() {
     companion object {
         //所有任务需要等待的时间
         private const val WAITING_TIME = 10_000L
-        fun create(): AppStartTaskDispatcher {
-            return AppStartTaskDispatcher()
+        fun create(): StartTaskDispatcher {
+            return StartTaskDispatcher()
         }
     }
 }

+ 38 - 12
frame/startup/src/main/java/com/adealink/frame/startup/executor/TaskExecutorManager.kt

@@ -1,9 +1,7 @@
 package com.adealink.frame.startup.executor
 
-import com.adealink.frame.coroutine.dispatcher.Dispatcher
 import com.adealink.frame.thread.NamedThreadFactory
 import java.util.concurrent.BlockingQueue
-import java.util.concurrent.ExecutorService
 import java.util.concurrent.Executors
 import java.util.concurrent.LinkedBlockingQueue
 import java.util.concurrent.RejectedExecutionHandler
@@ -15,11 +13,11 @@ import kotlin.math.min
 class TaskExecutorManager private constructor() {
     //获得cpu密集型线程池,因为占据CPU的时间片过多的话会影响性能,所以这里控制了最大并发,防止主线程的时间片减少
     //CPU 密集型任务的线程池
-    val mainThreadPoolExecutor: ThreadPoolExecutor
+    val cpuThreadPoolExecutor: ThreadPoolExecutor
 
     //获得io密集型线程池,有好多任务其实占用的CPU time非常少,所以使用缓存线程池,基本上来着不拒
     // IO 密集型任务的线程池
-    val subThreadPoolExecutor: ExecutorService
+//    internal val ioThreadPoolExecutor: ExecutorService
 
     //线程池队列
     private val mPoolWorkQueue: BlockingQueue<Runnable> = LinkedBlockingQueue()
@@ -31,15 +29,40 @@ class TaskExecutorManager private constructor() {
     //初始化线程池
     init {
         //CPU 密集型任务的线程池
-        mainThreadPoolExecutor = ThreadPoolExecutor(
+        cpuThreadPoolExecutor = ThreadPoolExecutor(
             CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS.toLong(), TimeUnit.SECONDS,
-            mPoolWorkQueue, NamedThreadFactory("startup-cpu", Thread.NORM_PRIORITY), mHandler
+            mPoolWorkQueue, NamedThreadFactory("startup-thread", Thread.MAX_PRIORITY), mHandler
         )
-        mainThreadPoolExecutor.allowCoreThreadTimeOut(true)
+        cpuThreadPoolExecutor.allowCoreThreadTimeOut(true)
 
-        //io密集型线程池
-        subThreadPoolExecutor = Dispatcher.wenextThreadPoolExecutor
-        //Executors.newCachedThreadPool(NamedThreadFactory("startup-io", Thread.NORM_PRIORITY))
+        cpuThreadPoolExecutor.taskCount
+
+//        //io密集型线程池
+//        ioThreadPoolExecutor = Dispatcher.wenextThreadPoolExecutor
+    }
+
+    fun getMaxTaskCount(): Int {
+        // 获取最大线程数
+        val maximumPoolSize: Int = cpuThreadPoolExecutor.maximumPoolSize
+        return (maximumPoolSize * MAX_LOAD_FACTOR).toInt()
+    }
+
+    /**
+     * 线程池负荷太高
+     */
+    fun isBusy(): Boolean {
+        // 获取当前活跃线程数
+        val activeCount: Int = cpuThreadPoolExecutor.getActiveCount()
+        // 获取当前池中的线程数
+        val poolSize: Int = cpuThreadPoolExecutor.getPoolSize()
+        // 获取核心线程数
+        val corePoolSize: Int = cpuThreadPoolExecutor.corePoolSize
+        // 获取最大线程数
+        val maximumPoolSize: Int = cpuThreadPoolExecutor.maximumPoolSize
+        // 获取任务队列中的待处理任务数
+        val queueSize: Int = cpuThreadPoolExecutor.queue?.size ?: 0
+        // 计算当前负荷率 (活跃线程 + 待处理任务数量 >= 最大线程 * MAX_LOAD_FACTOR)
+        return (activeCount + queueSize) >= maximumPoolSize * MAX_LOAD_FACTOR
     }
 
     companion object {
@@ -47,11 +70,14 @@ class TaskExecutorManager private constructor() {
             TaskExecutorManager()
         }
 
+        //线程池最大负荷量
+        private const val MAX_LOAD_FACTOR = 1.2f
+
         //CPU 核数
         private val CPU_COUNT = Runtime.getRuntime().availableProcessors()
 
-        //线程池线程数
-        private val CORE_POOL_SIZE = max(2.0, min((CPU_COUNT - 1).toDouble(), 5.0)).toInt()
+        //线程池线程数(CPU_COUNT-1留给主线程一个)
+        val CORE_POOL_SIZE = max(2.0, min((CPU_COUNT - 1).toDouble(), 5.0)).toInt()
 
         //线程池线程数的最大值
         private val MAXIMUM_POOL_SIZE = CORE_POOL_SIZE

+ 0 - 22
frame/startup/src/main/java/com/adealink/frame/startup/runnable/AppStartTaskRunnable.kt

@@ -1,22 +0,0 @@
-package com.adealink.frame.startup.runnable
-
-import android.os.Process
-import android.util.Log
-import com.adealink.frame.startup.TAG_START_UP
-import com.adealink.frame.startup.dispatcher.AppStartTaskDispatcher
-import com.adealink.frame.startup.task.AppStartTask
-
-class AppStartTaskRunnable(private val mAppStartTask: AppStartTask, private val mAppStartTaskDispatcher: AppStartTaskDispatcher) : Runnable {
-    override fun run() {
-        if (!mAppStartTask.isRunOnMainThread) {
-            Process.setThreadPriority(mAppStartTask.priority())
-        }
-        mAppStartTask.waitToNotify()
-        val startTime = System.currentTimeMillis()
-        Log.d(TAG_START_UP, "${mAppStartTask::class.java} start")
-        mAppStartTask.run()
-        Log.d(TAG_START_UP, "${mAppStartTask::class.java} end, cost ${System.currentTimeMillis() - startTime}")
-        mAppStartTaskDispatcher.setNotifyChildren(mAppStartTask)
-        mAppStartTaskDispatcher.markAppStartTaskFinish(mAppStartTask)
-    }
-}

+ 25 - 0
frame/startup/src/main/java/com/adealink/frame/startup/runnable/StartTaskRunnable.kt

@@ -0,0 +1,25 @@
+package com.adealink.frame.startup.runnable
+
+import android.os.Process
+import com.adealink.frame.log.Log
+import com.adealink.frame.startup.TAG_START_UP
+import com.adealink.frame.startup.dispatcher.StartTaskDispatcher
+import com.adealink.frame.startup.task.StartUpTask
+import com.adealink.frame.util.isMainThread
+
+class StartTaskRunnable(private val mStartUpTask: StartUpTask, private val mStartTaskDispatcher: StartTaskDispatcher) : Runnable {
+    override fun run() {
+        if (!mStartUpTask.isRunOnMainThread) {
+            Process.setThreadPriority(mStartUpTask.priority())
+        }
+        Log.i(TAG_START_UP, "${mStartUpTask::class.java} start, thread:${Thread.currentThread()}, isMainThread:${isMainThread()}")
+        val startTime = System.currentTimeMillis()
+        mStartUpTask.waitToNotify()
+        Log.i(TAG_START_UP, "${mStartUpTask::class.java} start delay: ${System.currentTimeMillis() - startTime}")
+        mStartUpTask.run()
+        val costTime = System.currentTimeMillis() - startTime
+        Log.i(TAG_START_UP, "${mStartUpTask::class.java} end, cost: $costTime")
+        mStartTaskDispatcher.setNotifyChildren(mStartUpTask)
+        mStartTaskDispatcher.markAppStartTaskFinish(mStartUpTask, costTime)
+    }
+}

+ 4 - 4
frame/startup/src/main/java/com/adealink/frame/startup/task/AppStartTask.kt → frame/startup/src/main/java/com/adealink/frame/startup/task/StartUpTask.kt

@@ -6,12 +6,12 @@ import com.adealink.frame.startup.executor.TaskExecutorManager
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.Executor
 
-abstract class AppStartTask : TaskInterface {
+abstract class StartUpTask : TaskInterface {
 
     //是否在主线程执行
     abstract val isRunOnMainThread: Boolean
 
-    override val dependsTaskList: List<Class<out AppStartTask>>
+    override val dependsTaskList: List<Class<out StartUpTask>>
         get() = emptyList()
 
     // 当前Task依赖的Task数量(等父亲们执行完了,孩子才能执行),默认没有依赖
@@ -27,7 +27,7 @@ abstract class AppStartTask : TaskInterface {
     }
 
     override fun priority(): Int {
-        return Process.THREAD_PRIORITY_BACKGROUND
+        return Process.THREAD_PRIORITY_FOREGROUND
     }
 
     //执行任务代码
@@ -39,7 +39,7 @@ abstract class AppStartTask : TaskInterface {
     }
 
     override fun runOnExecutor(): Executor {
-        return TaskExecutorManager.instance.subThreadPoolExecutor
+        return TaskExecutorManager.instance.cpuThreadPoolExecutor
     }
 
     override fun needWait(): Boolean {

+ 9 - 9
frame/startup/src/main/java/com/adealink/frame/startup/util/AppStartTaskSortUtil.kt → frame/startup/src/main/java/com/adealink/frame/startup/util/StartUpTaskSortUtil.kt

@@ -1,12 +1,12 @@
 package com.adealink.frame.startup.util
 
-import com.adealink.frame.startup.task.AppStartTask
+import com.adealink.frame.startup.task.StartUpTask
 import com.adealink.frame.startup.util.model.TaskSortModel
 import java.util.ArrayDeque
 import java.util.Deque
 
 
-object AppStartTaskSortUtil {
+object StartUpTaskSortUtil {
     /**
      * 拓扑排序
      * taskIntegerHashMap每个Task的入度(key= Class < ? extends AppStartTask>)
@@ -15,13 +15,13 @@ object AppStartTaskSortUtil {
      * deque 入度为0的Task
      */
     fun getSortResult(
-        startTaskList: List<AppStartTask>,
-        taskHashMap: HashMap<Class<out AppStartTask>, AppStartTask>,
-        taskChildHashMap: HashMap<Class<out AppStartTask>, MutableList<Class<out AppStartTask>>>
-    ): List<AppStartTask> {
-        val sortTaskList: MutableList<AppStartTask> = ArrayList()
-        val taskIntegerHashMap = HashMap<Class<out AppStartTask>, TaskSortModel>()
-        val deque: Deque<Class<out AppStartTask>> = ArrayDeque()
+        startTaskList: List<StartUpTask>,
+        taskHashMap: HashMap<Class<out StartUpTask>, StartUpTask>,
+        taskChildHashMap: HashMap<Class<out StartUpTask>, MutableList<Class<out StartUpTask>>>
+    ): List<StartUpTask> {
+        val sortTaskList: MutableList<StartUpTask> = ArrayList()
+        val taskIntegerHashMap = HashMap<Class<out StartUpTask>, TaskSortModel>()
+        val deque: Deque<Class<out StartUpTask>> = ArrayDeque()
         for (task in startTaskList) {
             if (!taskIntegerHashMap.containsKey(task.javaClass)) {
                 taskHashMap[task.javaClass] = task

+ 2 - 2
module/message/src/main/java/com/adealink/weparty/message/manager/IMessageManager.kt

@@ -4,7 +4,7 @@ import com.adealink.frame.base.Rlt
 import com.adealink.frame.frame.IBaseFrame
 import com.adealink.frame.network.data.Res
 import com.adealink.frame.router.Router
-import com.adealink.frame.startup.IStartUpTask
+import com.adealink.frame.startup.IAppStartUpTask
 import com.adealink.weparty.message.listener.IMessageListener
 import com.adealink.weparty.module.account.Account
 import com.adealink.weparty.module.message.data.CustomerInfo
@@ -13,7 +13,7 @@ import com.adealink.weparty.module.message.data.SessionInfo
 import com.adealink.weparty.module.profile.data.UserFamilySetting
 import com.adealink.weparty.module.room.Room
 
-interface IMessageManager : IBaseFrame<IMessageListener>, IStartUpTask {
+interface IMessageManager : IBaseFrame<IMessageListener>, IAppStartUpTask {
     suspend fun batchQuerySayHiState(uidSet: Set<Long>): Rlt<Map<Long, Boolean>>
     fun getSayHiState(uid: Long): Boolean
     /**