App体系化优化之启动优化(一启动时间分析)

   日期:2020-10-02     浏览:115    评论:0    
核心提示:app的启动模式分为三种:1.冷启动冷启动耗时最久,衡量的保准最多Click Event - IPC - Process.start - ActivityThread - bindApplication - LifeCycle - ViewRootImpl用户在桌面点击app 发起一个IPC操作,通过Process.start 然后创建ActivityThread,是每一个单独app进程的入口,消息循环的创建,然后通过反射创建application调用于application相关的生命周期,

app的启动模式分为三种:

1.冷启动

冷启动耗时最久,衡量的保准最多

Click Event - IPC - Process.start - ActivityThread - bindApplication - LifeCycle - ViewRootImpl

用户在桌面点击app 发起一个IPC操作,通过Process.start 然后创建ActivityThread,是每一个单独app进程的入口,消息循环的创建,然后通过反射创建application调用于application相关的生命周期,最后就是创建我们常用的Activity的生命周期,当Activity的生命周期完毕后,就会进入到ViewRootImpl进行真正的界面绘制。

2.热启动

最简单,最快

后台 - 前台

3.温启动

相对冷启动比较快一些

LifeCycle

 

根据互联网行业的8秒原则,我们需要控制冷启动的启动速度,那么我们来看冷启动都做了一些什么呢?

冷启动:

1.启动app

2.加载空白页(图片替换)

3.创建进程

4.创建application

5.启动出线程

6.创建MainActivity

7.加载布局

8.布置屏幕

9.首帧绘制

查看启动耗时:

方法1:

命令:adb命令观察app启动的时间  (线下使用,无法带到线上)

adb shell am start -W -n 包名/类名   或者    adb shell am start -W 包名/类名

比如我自己的app:adb shell am start -W -n com.yinyan.ywf.app/com.cfs.app.ui.activity.sp.SpActivity

macdeMac-mini:~ mac$ adb shell am start -W -n com.yinyan.ywf.app/com.cfs.app.ui.activity.sp.SpActivity
Starting: Intent { cmp=com.yinyan.ywf.app/com.cfs.app.ui.activity.sp.SpActivity }
Status: ok
Activity: com.yinyan.ywf.app/com.cfs.app.ui.activity.sp.SpActivity
ThisTime: 2654  最后Activity启动耗时
TotalTime: 2654 所有Activity启动的耗时(包含闪屏)
WaitTime: 2673  AMS启动Activity的总耗时
Complete

方法2:手动打点(线上捕获)


public class LaunchTimer {

    private static long sTime;

    public static void startRecord(){
        sTime = System.currentTimeMillis();
    }

    public static void endRecord(){
        long cost = System.currentTimeMillis() - sTime;
        Logger.i("cost = ",cost);
    }
}

启动时间记录,在Application的attachBaseContext()方法中调用 LaunchTimer.startRecord()

结束的调用建议放在自己adapter的第一个item加载出来,或者activity渲染完毕的生命周期中,不要放在首帧回调(onWindowFocusChanged)的位置,因为首帧回调未必绘制完毕了页面,是不准确的。

现在我们形成对比 我们先看看SophixApplitcation

 @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        LaunchTimer.startRecord();
//         如果需要使用MultiDex,需要在此处调用。
//         MultiDex.install(this);
        initSophix();
    }

接下来对比一下首帧绘制和FeedShow之后的启动时间

IndexActivity

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        LaunchTimer.endRecord("onWindowFocusChanged");
        freshFragmnet();
    }
IndexActivity - HomeFragment - BusinessAdapter中的第一个Feed加载出来的时候

mHasRecorded自己声明一下即可 布尔类型

 @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
        Holder holder = (Holder) viewHolder;

        
        if(position == 0 && !mHasRecorded){
            mHasRecorded = true;
            holder.ll_business.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    holder.ll_business.getViewTreeObserver().removeOnPreDrawListener(this);
                    LaunchTimer.endRecord("FeedShow");
                    return true;
                }
            });
        }
}

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服