提升UI流畅度

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012359498/article/details/84582033

之前看过这样一篇文章对应用性能提示有很大帮助的一篇文章Android应用性能剖析全攻略

总结了几个提升ui流畅度的可优化点

1.远离主线程

主线程进行的很多耗时操作,过多的循环遍历,甚至轻微的逻辑,常见的像读缓存、sharedpreferences都会造成轻微的卡顿,严重的甚至ANR,sharedpreferences还是建议存放一些小数据的东西

2.布局过于复杂view的层次过多

布局的层次越多,渲染的速度越慢,能用一个控件可以搞定的千万不要用多个控件,少用LinearLayout,多用RelativeLayout,他能够多个方向进行排版,
常见的优化像Adapter,结构简单的话只需要一个控件就可以了,不需要外层再嵌套个layout

3.敏感方法里少做不相关的操作

比如onDraw, onMeasure, onLayout里面只做绘制方面的事情,如果要做需要handler发送消息去执行

4.避免频繁的addView和removeView

一般出现在实现动画的常见,使用这种方式来实现,这都会不断的触发measure/onMeasure,layout/onLayout和View的重绘。

View的层次越少,数量越少渲染越快,布局层面上的优化:

删除没有用的View

除去无必要的嵌套,比如当内部仅有一个View时,外面就没有必要再加一个ViewGroup了

多使用RelativeLayout。它能够随意的排版View,三维上的方位都可以搞定,所以对象像列表的Cell之类的,一个RelativeLayout基本上就可以搞定。

用TextView的drawable属性来组合图片+文字

用merge来减少层次

对于某些情况才用到的View,就使用ViewStub,然后在需要显示的时候再inflate。也就是所谓的延时和按需渲染

尽量不要用背景图片,特别整个Activity大小的背景,费内存,占资源

尽可能用矢量图形,比如颜色,drawable,shape,icon font等等

对于列表(List和Grid)优化除了上面提到的,还要注意使用组件传回来的convertView以及ViewHolder。convertView可以复用View对象,避免inflate过多的View。ViewHolder模式主要是减少findViewById的调用。

用StrictMode来检测主线程中所执行的耗时操作,这也是一大优化项,如下,可以在Activity入口加入,检测到并打印log,包含方法的耗时时间

  StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectDiskReads()
                .detectDiskWrites()
                .detectNetwork()
//                .penaltyDialog()//弹出违规提示对话框
                //   这里可以替换为detectAll()就包括了磁盘读写和网络I / O
                .penaltyLog()
//打印logcat,当然也可以定位到dropbox,通过文件保存相应的log
                .build());
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                .detectLeakedSqlLiteObjects()
//探测SQLite数据库操作
                .penaltyLog()
//打印logcat
                .penaltyDeath()
                .build());

布局调试工具hierarchyview

这个工具很明显就是用来调试布局的,它能以可视化的方式展示View的层次结构,顺带显示每一层View的渲染速度。运行方法是找到SDK/tools/运行hierarchyviewer.

注意:默认情况下只有调试的ROM(build with eng)或者用模拟器才能抓到View的层次信息(否则,应用的页面就很容易被破解了),对于可控制源码的可以用开源库来解决这个问题。

关于ViewServer,官方提供了一个ViewServer.java,需要接入到自己的应用中去,才能使用hierarchyview,使用的正确姿势:

  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        if (getIntent().getExtras() != null) mCounter = getIntent().getExtras().getInt("counter");
        ((TextView) findViewById(R.id.label)).setText("Activity #" + (mCounter + 1));
        ViewServer.get(this).addWindow(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        ViewServer.get(this).removeWindow(this);
    }

    @Override
    public void onResume() {
        super.onResume();
        ViewServer.get(this).setFocusedWindow(this);
    }

针对这个工具,对自己的应用进行了优化

优化前的版本view的数量:131

3.4.0

优化前的版本view的数量:127

3.4.5

优化后的版本view的数量:105

3.4.6

优化经验:不经常显示的用ViewStub加载,多用merge来减少层次,把整个层次往前提,减少包裹,就能大幅度的提升流畅度和过度绘制

猜你喜欢

转载自blog.csdn.net/u012359498/article/details/84582033
今日推荐