背景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,一步步下去,最后定位到以下的位置:
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毫秒,提高仍是很大的!
码字不易,期待各位的赞扬!!!