美文网首页
冷启动优化

冷启动优化

作者: 旺仔_100 | 来源:发表于2022-08-30 18:41 被阅读0次

    冷启动优化主要优化两个方面

    • Application 性能优化
    • App启动页性能优化
      业务优化不在本章优化范围内。本章主要量化性能检测数据和问题,并针对其做性能优化和修改。

    冷启动速度优化

    冷启动耗时统计
    adb shell am start -S -W [packageName] / [activityName]
    
    • -s 表示杀死程序重启
    • -w 启动并输出相应的数据
    • packageName applicationId
    • activityName 启动页的名称,Luauncher Activity

    执行上述命令,成功唤起应用,并在控制台输出如下数据:


    image.png

    LaunchState : 启动模式,这里是冷启动
    waitTime:系统启动耗时 = TotalTime +系统资源时间
    totalTime:应用自身启动时间 = 该Activity启动 + Application系统资源启动时间

    对于冷启动,我们一般关注的是totalTime,该时间大致概括为:Application的onCreate到Activity的onWindowFouchChange方法的总和,这个初步理解为从应用启动到Activity获取焦点,业务执行的总时间。

    冷启动耗时堆栈观察方法

    在API>=26的版本中,建议使用CPU profile 或者Debug.startMethodTracing进行监控导出trace文件。

    • CPU profile
      这种方式不知道冷启动怎么监控,但是可以手动采样启动后某一段时间。


      image.png
    • Debug.startMethodTracing
      由于冷启动涉及到业务应用层面是:Activity启动+Application系统资源启动时间。所以,我们在Application中开始采集,在第一个Activity的onWindowFouchChange里面停止采集,并输出trace文件。
    //Application 的onCreate代码
     fun  applicationTrace(){
             // 保存trace的文件
             val file  =  File(Environment.getExternalStorageState(),"myApp.trace")
             //采集方式有两种,根据需要选择其一
             //通过采样的方式追踪堆栈信息
    
    //         if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ){
    //             //通过采样方式追踪堆栈信息,需要制定文件保存目录,文件大小 单位M,采样间隔时间us
    //             Debug.startMethodTracing(file.absolutePath,8,1000)
    //         }
    
             //第二种方式全采样
             Debug.startMethodTracing(file.absolutePath)
    
        }
    
    //MainActivity的代码
       override fun onWindowFocusChanged(hasFocus: Boolean) {
            super.onWindowFocusChanged(hasFocus)
            Debug.stopMethodTracing()
        }
    
    Trace日志文件的阅读

    在导出.trace文件后,直接拖到android studio中,便可以对程序运行的堆栈进行分析。


    trace.png

    上图是trace文件打开后的效果,是基于CPU和线程的运行状况,针对启动优化,需要关注几个点:
    (1)CPU运行时间轴,横向拖动可以选择时间范围。
    (4)当前设备CPU轮转的线程:点击可以选择需要查看的线程,我们重点关注主线程
    (2)当前选择线程,跟随时间轴各个方法栈的调用情况和耗时情况。其不同颜色分别代表:

    • 黄色 :android系统方法(Framwork层代码,如果需要最终最底层的方法,需要C/C++代码调用栈。
    • 蓝色:代表java JDK方法
    • 绿色:属于当前进程执行的方法,包括类加载器和我们的业务代码。(启动优化主要是这部分)
      (3)各个方法栈的调用顺序和耗时情况。可以选择不用的排序方式和视图。
    Application优化

    通过trace文件,我们发现,耗时最长的是Application的onCreate方法,其中initMudleFactory、initURS、Unicore.init、initUmeng都比较耗时。
    查看这几个三方库初始化源码,发现都做了现场安全,所以直接放到子线程中执行。
    对于一些不能放到子线程中执行的三方库的初始化,我们可以使用IdleHandle去处理,它会在主线程空闲的时候去执行。

    Launcher Activity优化

    思路还一样,查看trace文件,在Activity的onCreate中有三个地方耗时比较多,initActionbar,EventBus.register,setContentView。下面分别做优化:
    1.initActionbar
    通过trace图可以看到最耗时的是getSupportActionBar,实际的欢迎页面不需要actionBar,所以,我们重写了父类方法,把super方法去掉了。
    2.EventBus.register
    Eventbus2.0是通过注解加反射实现的,性能相对差,所以我们可以升级到3.0.这个是通过编译生成文件,不会对运行时性能造成影响。
    3.setContentView

     AsyncLayoutInflater(this).inflate(
                R.layout.activity_welcome, null
            ) { view: View?, resid: Int, parent: ViewGroup? ->
                setContentView(
                    view
                )
            }
    

    通过异步加载布局是一个方面,优化布局是另一个方面。

    优化方法总结

    1.合理的使用异步加载、延迟初始化、懒加载机制去初始化三方库。
    2.主线程中避免做耗时操作,比如io,数据的读写。
    3.简化launcher Activity的布局,采用两种方式优化:

    • 采用ConstraintLayout减少布局的层数,降低过度渲染
    • 使用 androidx.asynclayoutinflater:asynclayoutinflater进行异步加载xml

    4.合理的使用idleHandler进行延迟初始化

    /**
    
     * 需要在当前线程中处理耗时任务,并且并不需要马上执行的话,可以使用IdleHandler
    
     * 这样该任务可以消息队列空闲时,被处理
    
     */
    
    Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
    
        @Override
    
        public boolean queueIdle() {
    
            //此处添加处理任务
    
    
    
            //返回值为false:则执行完毕之后移除这条消息,
    
            //返回值为true:则则执行完毕之后依然保留,等到下次空闲时会再次执行,
    
            return false;
    
        }
    
    });
    
    

    5.使用严苛模式(Strict Mode)
    该模式并不能自动帮我们优化性能,但是可以检测出我们的代码或者三方库代码会阻塞Main线程的事情(例如磁盘操作,网络操作),并将他们提示出来,我们在开发阶段可以修改掉。

    /**
    
     * 开启严苛模式,当代码有违规操作时,可以通过Logcat或崩溃的方式提醒我们
    
     */
    
    private void startStrictMode() {
    
        if (BuildConfig.DEBUG) { //一定要在Debug模式下使用,避免在生产环境中发生不必要的崩溃和日志输出
    
    
    
            //线程检测策略
    
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
    
                    .detectDiskReads()  //检测主线程磁盘读取操作
    
                    .detectDiskWrites() //检测主线程磁盘写入操作
    
                    .detectNetwork() //检测主线程网络请求操作
    
                    .penaltyLog() //违规操作以log形式输出
    
                    .build());
    
    
    
            //虚拟机检测策略
    
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
    
                    .detectLeakedSqlLiteObjects() //检测SqlLite泄漏
    
                    .detectLeakedClosableObjects() //检测未关闭的closable对象泄漏
    
                    .penaltyDeath() //发生违规操作时,直接崩溃
    
                    .build());
    
        }
    
    }
    
    
    
    

    相关文章

      网友评论

          本文标题:冷启动优化

          本文链接:https://www.haomeiwen.com/subject/fmcqnrtx.html