两个目标:
1、获取界面整体绘制时间。
2、获取界面中每个控件的绘制时间。
优化方向:选出界面绘制时间最长的,然后再根据控件绘制时间等进行优化。
界面绘制时间获取方式,方法很多种,我这里用的是AOP模式,仅做参考。
同时也可参照:https://blog.csdn.net/Hello___Sunshine/article/details/93629281
第一步引入插件:
dependencies {
.....
classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.0'//AOP模式监测
}
创建监测类,并实现功能:
**
* Created by tanbo on 2019-07-04.
* Hello World!
*/
@Aspect
public class ActivityCreateTimeAop {
@Around("execution(* android.app.Activity.setContentView(..))")
public void onCreateTime(ProceedingJoinPoint joinPoint){
long start = System.currentTimeMillis();
try {
joinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
TBTools.log().i(joinPoint.getSignature().toString() +" onCreate 执行时间>>>"+(System.currentTimeMillis()-start));
}
}
运行项目后,控制台会输出当前界面的绘制时间:
{Thread:main}[tag=>APPAplication$2.afterHookedMethod(line:68):] ==========> void android.support.v7.app.AppCompatActivity.setContentView(int) onCreate 执行时间>>>84
可以看出当前界面的setContentView方法绘制执行时间,跳转其他界面时,会输出当前界面的绘制时间。
获取界面绘制时间到此结束。
---------------------------------------------------------------------------------------------------------------------------------------------------------
获取界面中所有控件绘制时间:
我这里是通过LayoutInflaterCompat.setFactory方式进行获取,在界面onCreate方法中,super.Oncreate之前写入我们的代码,通过拦截获取到当前界面中控件的绘制消耗时间,直接上代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
LayoutInflaterCompat.setFactory(LayoutInflater.from(this), new LayoutInflaterFactory() {
@Override
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
//获取指定类型控件的方法
// if(!TextUtils.isEmpty(name) && name.equals("Button")){
// Button button = new Button(context, attrs);
// return button;
// }
//替换成自己的控件方法
// if(!TextUtils.isEmpty(name) && name.equals("TextView")){
// Button button = new Button(context, attrs);
// return button;
// }
long start = System.currentTimeMillis();
AppCompatDelegate delegate = getDelegate();
View view = delegate.createView(parent, name, context, attrs);
TBTools.log().i("main activity"+name+" 绘制耗时>>>> "+(System.currentTimeMillis() - start));
return view;
}
});
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
运行以上代码,输出如下:
{Thread:main}[tag=>APPAplication$2.afterHookedMethod(line:68):] ==========> main activityImageView 绘制耗时>>>> 1
{Thread:main}[tag=>APPAplication$2.afterHookedMethod(line:68):] ==========> main activityButton 绘制耗时>>>> 6
{Thread:main}[tag=>APPAplication$2.afterHookedMethod(line:68):] ==========> main activityTextView 绘制耗时>>>> 3
{Thread:main}[tag=>APPAplication$2.afterHookedMethod(line:68):] ==========> main activityFrameLayout 绘制耗时>>>> 0
{Thread:main}[tag=>APPAplication$2.afterHookedMethod(line:68):] ==========> main activityImageView 绘制耗时>>>> 2
{Thread:main}[tag=>APPAplication$2.afterHookedMethod(line:68):] ==========> main activityRelativeLayout 绘制耗时>>>> 0
{Thread:main}[tag=>APPAplication$2.afterHookedMethod(line:68):] ==========> main activityTextView 绘制耗时>>>> 3
这里会输出当前界面中所有控件的绘制时间,我们可以根据耗时长短进行针对性的优化操作。
同时LayoutInflaterCompat.setFactory也可用于其他很多操作,如替换view,夜间模式等操作,详情谷歌百度。
-----------------------------------------------------------------------------------------------------------------------------------------
总结:
以上两种方式进行布局选择优化,减少了代码侵入性,实现方式更美观,但优化的同时最好也结合其他工具进行操作,如sys等。
方式千千万,自己用着顺手就好。