Android 启动优化

404 阅读1分钟

Android 车载性能优化-启动优化

统计启动耗时统计

adb shell 命令

PS C:\Users\EDY> adb shell pidof com.autolink.launcher
2975
PS C:\Users\EDY> adb shell kill 2975
/system/bin/sh: kill: 2975: Operation not permitted
PS C:\Users\EDY> adb root
restarting adbd as root
PS C:\Users\EDY> adb shell kill 2975
PS C:\Users\EDY> adb shell am start -W com.autolink.launcher/com.autolink.launcher.MainActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.autolink.launcher/.MainActivity }
Status: ok
LaunchState: WARM
Activity: com.autolink.launcher/.MainActivity
TotalTime: 3098
WaitTime: 3101
Complete
PS C:\Users\EDY>

需要关注的数据为 TotalTime WaitTime

  • TotalTime 所有 Activity 启动耗时
  • WaitTime AMS 启动 Activity 的耗时

adb 命令只能线下使用,不能带到线上,获取的耗时并非严谨精确

手动打点

// 在 attachBaseContext 中记录开始时间
    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(base)
        LauncherTime.startTime()
    }
// 在 MainActivity 中的 onWindowFocusChanged 中记录结束时间
    override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)
        LauncherTime.endTime("onWindowFocusChanged")
    }

结束时间,更准确的地方应该是 Feed 的第一帧 addOnDrawListener,这个值比在 onWindowFocusChanged要大,为了方便就在 onWindowFocusChanged中记录结束时间

花费时间为 onWindowFocusChanged costTime = 3494

  • 埋点方式获取的数据比 adb 要准确
  • 埋点方式可以在线上使用

工具选择 traceView & profile

traceview

Debug.startMethodTracing("App") Debug.stopMethodTracing() 生成文件在 sd 卡:Android/data/packagename/files

方式一:Executors.newFixedThreadPool

正常在 Application 中初始化

        NaviApplication.onCreate(this)
        CarSdkManager.init(this)
        CarHelper.init(this)
        UserLockHelper.init(this)
        MMKV.initialize(this)

耗时为 :APP onCreate costTime = 305

采用 Executors 后时间为

    // 根据机型核数来确定线程池大小
    val count = Runtime.getRuntime().availableProcessors()
    val corePoolSize = 2.coerceAtLeast((count - 1).coerceAtMost(4))

     val execute = Executors.newFixedThreadPool(corePoolSize)
     execute.submit { NaviApplication.onCreate(this) }
     execute.submit { CarSdkManager.init(this) }
     execute.submit { CarHelper.init(this) }
     execute.submit { UserLockHelper.init(this) }
     execute.submit { MMKV.initialize(this) }

耗时为 :APP onCreate costTime = 50

Q:以上初始化放到一个 submit 中是否可行?

A:如果放到一个 submit 中,就只使用了一个线程去完成异步任务,其余的线程闲置。

方式二:利用 CountDownLatch 控制初始化


        val countDownLatch = CountDownLatch(1)
        execute.submit {
            MMKV.initialize(this)
            countDownLatch.countDown()
        }

        // 保证 MMkv 初始化完成
        countDownLatch.await()