美文网首页
ListView性能优化

ListView性能优化

作者: 53ba3f4ab566 | 来源:发表于2017-04-25 12:44 被阅读237次

ListView实在是使用的太频繁了,记录下ListView怎么在项目中去优化卡顿现象。首先想到的就是,这些是最基础的。其他:下拉刷新,分页加载,加载不同类型的item。

1 复用convertView,为什么复用convertView

ListView中的每一个Item显示都需要Adapter调用一次getView()的方法,这个方法会传入一个convertView的参数,这个方法返回的View就是这个Item显示的View。如果当Item的数量足够大,再为每一个Item都创建一个View对象,必将占用很多内存空间,即创建View对象(mInflater.inflate(R.layout.lv_item, null);从xml中生成View,这是属于IO操作)是耗时操作,所以必将影响性能。Android提供了一个叫做Recycler(反复循环)的构件,就是当ListView的Item从滚出屏幕视角之外,对应Item的View会被缓存到Recycler中,相应的会从生成一个Item,而此时调用的getView中的convertView参数就是滚出屏幕的缓存Item的View,所以说如果能重用这个convertView,就会大大改善性能.

这个convertView不存在时,即第一次使用它,我们就创建一个item布局的View对象并赋给convertView,以后使用convertView时,只需从convertView中getTag取出来就可以,不需要再次创建item的布局对象了。

google的新控件recycleView就是使用的viewholder模式。强制使用

2 使用static ViewHolder()

ViewHolder为什么声明为静态类?ViewHolder为什么能起到性能优化的作用?

A:非静态内部类拥有外部类对象的强引用,因此为了避免对外部类的引用,将内部类声明为static 。(一般写内部类的意图都是为了说明该类和宿主类关系密切,而private , static , final 这些可以单独拿出来说,static这个区别比较大,没有static修饰,说明此类必须依赖宿主类的对象;而有static修饰,就不依赖与对象的存在了,类名. 即可,整体类似方法上添加static。private这玩意,完全取决于你是否希望将此类暴露出去;final则是为了标明该类不可继承修改)。

A:在getView()方法中的操作是这样的:先从xml中创建view对象(inflate操作,我们采用了重用convertView方法优化),然后在这个view去findViewById,找到每一个item的子View的控件对象,如:ImageView、TextView等。这里的findViewById操作是一个树查找过程,也是一个耗时的操作,所以这里也需要优化,就是使用ViewHolder,把每一个item的子View控件对象都放在Holder中,当第一次创建convertView对象时,便把这些item的子View控件对象findViewById实例化出来并保存到ViewHolder对象中。然后用convertView的setTag将viewHolder对象设置到Tag中, 当以后加载ListView的item时便可以直接从Tag中取出复用ViewHolder对象中的,不需要再findViewById找item的子控件对象了。这样便大大提高了性能。

3使用异步线程加载图片(一般是用自己项目封装好的图片加载库ImageLoader,Picasso..)

除此之外 还有一些可以优化的地方:

Adapter核心的方法都是在getView方法中进行的。很多性能问题都是没有正确使用getView这个方法造成的。

Q1:在一次显示ListView界面时,getView会被执行几次?

Q2 :每次getVIew执行的时间该被控制在多少毫秒之内?

Q3:  getView中设置listener要注意什么?

首先我们要知道ListView的ItemView有一个复用机制,简单看如下图所示,ListView中有一个RecycleBin类复负回收不可见且可能被再次使用的ItemView,由ScrapView存储。

所以我在们设置Listener进就要注意,使用convertView时需要重新设置一个Listener,包括一些数据也需要重设置,不然可能会显示之前那个ItemView在回收前的状态。

在绘制ListView前往往要计算它的高度,所以一个ListView界面上可以看到6个ItemView,但是getView的执行次数却有可能是12次,多出的次数用来计算高度(这个可以通过设置ListView的height为0来避免)。所以要避免在getView中进行逻辑运算,两次计算同一逻辑完全是浪费。

1秒之内屏幕可以完成30帧的绘制,人才能看到它比较流畅(苹果是接近60帧,高于60之后人眼也无法分辨)。

每帧可使用的时间:1000ms/30 = 33.33 ms

每个ListView一般要显示6个ListItem,加上1个重用convertView:33.33ms/7 = 4.76ms

即是说,每个getView要在4.76ms内完成工作才会较流畅,但是事实上,每个getView间的调用也会有一定的间隔(有可能是由于handler在处理别的消息),UI的handler处理不好的话,这个间隔也可难会很大(0ms-200ms)。结论就是,留给getView使用的时间应该在4ms之内,如果不能控制在这之内的话,ListView的滑动就会有卡顿的现象。

4   在adapter中尽量减少逻辑判断,特别是耗时判断

5 避免GC(可以在LogCat中查看有没有GC的Log);

6 在快速滑动时不要加载图片(等列表慢下来或者停下来时再加载图片)给ListView实现

setOnScrollListener接口,并在OnScrollListener的onScrollStateChanged方法中判断列表是否处于快速滑动状态,如果是,停止加载图片。

7 将xml文件中ListVIew的ScrollingCache和animateCache这两个属性设置为false。默认是true

8 尽可能减少item的Layout层次,过多的嵌套消耗性能(View绘制相关)

9  在清单文件中对应的Activity设置硬件加速

相关文章

  • ListView和RecyclerView

    ListView ListView 性能如何优化 (主要在getView方法上优化:复用view,ViewHold...

  • MS(4):Android之性能优化篇

    六、性能及优化 1、App优化之性能分析工具 Android App优化之性能分析工具 2、ListView优化 ...

  • Android性能优化-ListView优化

    Android性能优化-ListView ListView的优化主要分为以下几点 1 convertView的复用...

  • Android开发艺术探索之性能优化笔记

    Android性能优化 一,优化内容 布局优化、绘制优化、内存泄漏优化、响应速度优化、ListView优化、Bit...

  • Android性能优化

    Android性能优化包括布局优化、绘制优化、内存优化、线程优化、响应速度优化、Bitmap优化和ListView...

  • Android进阶之性能优化

    一、性能优化分类 布局优化 绘制优化 内存泄漏优化 响应速度优化 ListView优化 Bitmap优化 线程优化...

  • Android知识点整理

    2018.6.11更新: Android性能优化之提高ListView性能的技巧 2018.5.15更新: htt...

  • ListView性能优化

    ListView实在是使用的太频繁了,记录下ListView怎么在项目中去优化卡顿现象。首先想到的就是,这些是最基...

  • Listview性能优化

    起因 鉴于最近有一个岗位晋升考核,并且自己一路走来的一些知识点没有进行过积累,也就借此机会,在这里简单的做一下纪录...

  • Android - ListView的优化

    ListView在应用中使用极为广泛,为了使ListView的滑动流畅,性能优化是必不可少的操作。在此提出三点优化...

网友评论

      本文标题:ListView性能优化

      本文链接:https://www.haomeiwen.com/subject/hnhvzttx.html