Android 性能优化工具 TraceView 简单使用

背景android

最近产品以及测试大佬反应快搜桌面进入搜索页面跳转较为缓慢,影响体验,为了优化这个问题,特意学习Android 性能优化工具 TraceView的 简单使用,这才有了本文。性能优化

正文bash

以下图打开android device monitor ,打开有点慢,请耐心等待:app


可能有些同窗会打不开,出现以下的错误:ide


重装一遍jdk,配好环境变量通常就没有问题了。android device monitor打开以后如图:函数


能够看到TraceView 集成了不少小工具,图上标红的1是个截取设备当前屏幕的工具,做为和测试后台交(si)流(bi)的神器,能作到有图有真相;图上标红的2因为展现当前页面视图层级结构,以下图:工具


能够看到右边上半部分能够很清晰看到当前页面视图的结构,下半部分显示的是选择的视图的一些信息,如位置信息等,这个工具的应用场景仍是很普遍的,好比产品大佬叫你改一个view的文本,有了这个工具你能够很快定位到要改的是哪一个,上图左边还有好多小工具,这些不是本次的重点,有机会再说,不得不说一句,Google 大法好!!post

言归正传,选中你要分析的进程,如图:性能


红色1表示的位置由原来的灰色不可用的状态变为可用状态,敲黑板啦,重点来了。这个按钮叫 start method profiling(开始方法分析),点击以后如图:学习


点击OK,会对接下来的操做进行跟踪分析,这里我点击了跳转搜索页面的操做,而后在点击刚刚那个按钮,注意到按钮变成了 stop method profiling(中止方法分析),稍等一下就有分析结果视图以下:


先简单介绍下这个视图,红色1主要表示当前选中方法调用的线程信息,红色2表示的的是时间线,当你点击红色3区域的时候,时间线视图会有相应的反馈,出现一个U型闪动,U型宽度就是方法的执行时间,能够将借助鼠标测量耗时,如图先放到起点:


注意红线部分表示当前时间,再把鼠标放到U型的结束位置,以下图:


二者相减就能知道方法耗时,其实这个功能有点鸡肋,通常不用,接下来我会介绍红色3区域的功能,更加方便:


能够看到这是个表格,表明的含义以下:

列名 含义
Name
该线程运行过程当中所调用的函数名
Incl Cpu Time
某函数占用的CPU时间,包含内部调用其它函数的CPU时间
Excl Cpu Time
某函数占用的CPU时间,但不含内部调用其它函数所占用的CPU时间
Incl Real Time
某函数运行的真实时间(以毫秒为单位),不含调用其它函数所占用的真实时间
Excl Real Time
某函数运行的真实时间(以毫秒为单位),不含调用其它函数所占用的真实时间
Call+Recur Calls/Total
某函数被调用次数以及递归调用占总调用次数的百分比
Cpu Time/Call
某函数调用CPU时间与调用次数的比。至关于该函数平均执行时间
Real Time/Call
同CPU Time/Call相似,只不过统计单位换成了真实时间

随便点击一个函数,Parent表示调用该方法的方法,Children表示该方法调用的方法 ,以下:


能够看到LauncherSearchActvity的oncreate方法耗时1006.735这个很不正常,再找到Children里面耗时最多的setContenView,一步步下去,最后定位到以下的位置:


能够看到是KeybordLayout中initView()方法,继续如图:


能够看到有些函数被重复调用了屡次,接下来就是分析优化这个方法了,先看下LauncherSearchActvity的界面:


左边的区域是KeybordLayout在initView()进行键码的初始化以下:

for (int i = 0; i < 6; i++) {
    for (int j = 0; j < 6; j++) {
        GonTextView mButton = new GonTextView(getContext());
        mButton.setFocusable(true);
        mButton.setGravity(Gravity.CENTER);
        if (j == 5) {
            mButton.setOnKeyListener(this);
            mButton.setTag(RIGHT_ROW_TAG);
        } else if (j == 0) {
            mButton.setId(DEFAULT_FOCUS_VIEW_ID);
        }
        mButton.getPaint().setFakeBoldText(true);
        mButton.setText(text_str[i][j]);
        ImageUtils.setBackground(mButton, R.drawable.sel_search_keyboard_item_solid);
        mButton.setTextColor(ResUtil.getColorList(isKeyboardNum(text_str[i][j]) ? R.color.sel_color_search_keyboard_item_123 : R.color.sel_color_search_keyboard_item_abc));
        keyboardAcherView.addView(mButton);

        //adapter
        mButton.setGonTextSize(38);
        mButton.setGonSize(70, 70);
        mButton.setGonMargin(j * (24 + 70), i * (24 + 70), 0, 0);

        // gain defualt focus item
        if (i == 0 && j == 0) {
            mButton.requestFocus();
        }
        mButton.setOnClickListener(v -> editText.append(((TextView) v).getText().toString()));
    }
}复制代码

能够看到36次循环,因此出现了上上张图的Call+Recur Calls/Total中的值是36/36,这边能够简单优化下,将键码GonTextView 放到一个集合里面,这步的操做放在子线程,而后在主线程遍历,addView()就行了,代码以下:

Observable.create((ObservableOnSubscribe<ArrayList<ViewWrapper>>) e -> {
            ArrayList<ViewWrapper> gonTextViews = initKeys();
            e.onNext(gonTextViews);
            e.onComplete();
        }).subscribeOn(RxCompat.getSchedulerOnDb())
                .observeOn(RxCompat.getSchedulerOnMain()).subscribe(new RxCompatObserver<ArrayList<ViewWrapper>>() {
            @Override
            public void onSubscribeCompat(Disposable d) {

            }

            @Override
            public void onNextCompat(ArrayList<ViewWrapper> gonTextViews) {
                GonRelativeLayout keyboardAcherView = (GonRelativeLayout) findViewById(R.id.ll_keys);
                keyboardAcherView.removeAllViews();

                for (ViewWrapper viewWrapper : gonTextViews) {
                    keyboardAcherView.addView(viewWrapper.gonTextView);
//                    keyboardAcherView.reqLa
                    //adapter
                    viewWrapper.gonTextView.setGonTextSize(38);
                    viewWrapper.gonTextView.setGonSize(70, 70);
                    viewWrapper.gonTextView.setGonMargin(viewWrapper.x * (24 + 70), viewWrapper.y * (24 + 70), 0, 0);
                    if (viewWrapper.x == 0 && viewWrapper.y == 0) {
                        viewWrapper.gonTextView.requestFocus();
                    }
                }
                setVisibility(VISIBLE);
                if (SpUtil.getBoolean(SpUtil.SpKey.IS_INPUT_METHOD, false)) {
                    postDelayed(() -> btnInputMethod.performClick(), 50);
                }
            }
        });
复制代码
private ArrayList<ViewWrapper> initKeys() {
    ArrayList<ViewWrapper> gonTextViews = new ArrayList<>(36);
    String[][] text_str = new String[][]{
            {"A", "B", "C", "D", "E", "F"},
            {"G", "H", "I", "J", "K", "L"},
            {"M", "N", "O", "P", "Q", "R"},
            {"S", "T", "U", "V", "W", "X"},
            {"Y", "Z", "1", "2", "3", "4"},
            {"5", "6", "7", "8", "9", "0"}
    };
    for (int i = 0; i < 6; i++) {
        for (int j = 0; j < 6; j++) {
            GonTextView mButton = new GonTextView(getContext());
            mButton.setFocusable(true);
            mButton.setGravity(Gravity.CENTER);
            if (j == 5) {
                mButton.setOnKeyListener(this);
                mButton.setTag(RIGHT_ROW_TAG);
            } else if (j == 0) {
                mButton.setId(DEFAULT_FOCUS_VIEW_ID);
            }
            mButton.getPaint().setFakeBoldText(true);
            mButton.setText(text_str[i][j]);
            ImageUtils.setBackground(mButton, R.drawable.sel_search_keyboard_item_solid);
            mButton.setTextColor(ResUtil.getColorList(isKeyboardNum(text_str[i][j]) ? R.color.sel_color_search_keyboard_item_123 : R.color.sel_color_search_keyboard_item_abc));
            gonTextViews.add(new ViewWrapper(i,j,mButton));


            mButton.setOnClickListener(v -> editText.append(((TextView) v).getText().toString()));
        }
    }
    return gonTextViews;
}复制代码

结果如图:


从原来的1000多毫秒到不到300毫秒,提高仍是很大的!

码字不易,期待各位的赞扬!!!

    

相关文章
相关标签/搜索