APP下载

Android中的ListView组件原理分析与优化

2016-05-21李新辉

计算机时代 2016年5期
关键词:优化

摘 要: ListView是开发Android应用程序中最常用的组件之一。分析了ListView基本工作机制和原理,提出了实际开发中合理使用ListView的必要性,阐述了提高ListView组件性能的四种优化方法和思路。通过这几种优化手段,能有效帮助改善ListView的工作性能,增强应用程序的操作流畅性,从而带来更佳的用户体验。

关键词: Android; ListView; 原理分析; 优化

中图分类号:TP393.09 文献标志码:A 文章编号:1006-8228(2016)05-34-05

Abstract: ListView is one of the most commonly used components in the development of Android application. This paper analyzes the basic working mechanism and principle of ListView, proposes the necessity of the reasonable use of ListView in practical development, and expounds four optimization methods and ideas to improve the performance of ListView components. These kinds of optimization methods can effectively help improving the performance of ListView, enhance the operation smoothness of the applications, and thus bring a better user experience.

Key words: Android; ListView; principle analysis; optimization

0 引言

在开发Android应用时,通常都会用到Android SDK提供的一个名为ListView的组件。ListView能够以列表行的形式展示数据,并且能够根据数据的长度自适应显示,比如手机里的通讯录就是使用ListView来显示联系人的信息,还有像新闻类和社交APP等也都用到了ListView组件,如图1所示。相比Button之类的简单控件而言,ListView的使用要复杂一些,而且如果处理不当就很容易在程序运行时引起一些性能问题,从而给用户留下不良的印象,因此掌握ListView的正确使用方法显得很重要。

1 ListView原理分析

ListView组件中的每一行被称为子项(Item),它既可以是一个文本信息,也可以是一个包含若干组件的布局视图。ListView的设计遵循适配器模式,即:显示的数据需通过一个中间角色的“适配器”提供,以确定数据的具体显示外观,这也导致ListView组件在使用上要比普通组件麻烦一些,但它具有较大的灵活性。

ListView显示列表元素需三方面配合,包括:展示数据的视图(View)、适配器(Adapter)以及具体数据(Data)。ListView并不直接获取数据进行展示,而是间接通过“适配器”来得到具体要展示的数据视图。Android SDK预定义了几种适配器类型,如SimpleAdapter等,但直接从BaseAdapter自定义派生类可以得到更大的灵活性。下面是一个名为MyAdapter的适配器的基础代码框架:

2 ListView的应用优化

考虑到ListView是Android应用普遍涉及的一个关键组件,如果使用不当,将会产生比较常见的“卡顿”现象。因此,合理地使用它可以极大改善应用程序的性能,带来更佳的用户体验。以下从四个方面考虑ListView的具体优化方法。

2.1 重用列表行视图

根据上面的分析,ListView需要借助Adapter适配器中的getView()得到显示的列表行视图对象。在getView()方法中,最简单的编程做法示例如下:

以上代码虽然简单直接,但却反复加载布局导致延时和内存消耗等问题,在数据量大的情况下,会有严重影响。考虑到getView()方法的convertView参数本身就是系统返回的可重用列表行视图对象,相当于这个视图对象已经被滑动到屏幕之外,可以拿来重复使用,此时只需判断convertView是否为null,以确定是手工产生新的视图对象,还是重用这个返回的视图对象[2]。优化后的示例代码如下:

2.2 ViewHolder绑定

重用系统返回的列表行视图对象,可以大大减少反复加载布局界面的次数。既然列表行视图对象可被重用,意味着这个视图对象中的子控件也是原来的。上面的示例代码中,每次定位子控件都使用findViewById()方法,尽管这样做没有问题,但反复调用将导致布局界面子控件的一次又一次的遍历,特别是在ListView快速滑动时,白白浪费了手机的处理时间。为避免这个问题,可把复用的列表行视图对象中的子控件引用地址保存起来[3],以省却重复定位子控件过程。为了达到目的,我们先根据具体业务需求,定义一个名为ViewHolder的静态内部类,其成员变量就是列表行视图对象中所需的子控件引用:

2.3 触摸滑动优化

在通过网络获取的数据量不大的情况下,或者数据本身存在于设备上,ListView的性能一般不会成为重点考虑的问题。但如果涉及到大量的后台数据,此时应合理规划ListView的滑动时机,适时加载显示数据。当用户正在操作时,如果上下滑动速度快,列表行视图就要切换得快,此时列表行视图的切换速度就容易成为一个瓶颈。这需要充分考虑ListView的状态以决定是否加载数据。如果ListView处于快速滚动的状态,我们可以让getView()方法返回一个只有空数据的视图对象,只有ListView处于普通速度触摸滑动,或者在静止空闲状态的时候,才真正加载数据以更新列表视图显示的内容[4]。

为了做到这一点,可以利用ListView的onScrollStateChanged()方法,以便开发者根据当前ListView的状态来决定做何种处理,包括空闲(IDLE)、普通滑动(SCROLL)、快速滚动(FLING)等三种:

在这里,我们定义了一个int型变量scrollState来指示ListView的当前状态,开发者可以在适配器的getView()方法中根据scrollState的值,决定是加载数据还是返回一个空视图。

2.4 网络数据本地缓存

对于从网络下载的数据,为节省手机流量,一般都要使用SQLite将其缓存到设备的存储卡上,当ListView上下滑动时,应首先检查设备本地是否已经存在缓存的数据,如果没有就启动线程将数据下载并缓存起来。由于SQLite是一个内置于Android的微型数据库,像图片之类的二进制数据就不适合存储。尽管可以将下载的图片以文件保存,不过,图片的显示却是一个费时和消耗内存的过程,特别是在ListView快速滑动时,很容易因为图片加载和内存反复垃圾收集造成卡顿现象,甚至处理不当还会引发内存溢出等问题。此时,可以使用LruCache缓存技术解决这个问题[5]。LruCache的基本原理是把最近使用的对象缓存起来,当内存占用达到一定水平时,把“最近最少使用”的对象从内存中移除,避免产生OutOfMemory异常。LruCache还可以结合文件缓存一起使用,LruCache充当一级缓存,文件充当二级缓存。如果LruCache中存在所需图像,ListView直接显示即可。如果LruCache中没有但存储卡上有图片文件,此时就加载图像到内存,缓存到LruCache并送给ListView显示。只有当LruCache和存储卡上均不存在所需图像时,才启动线程从网络下载。当图片下载完毕,在保存文件到存储卡的同时,还将图像加载到LruCache中。通过这种机制,可以让ListView快速地加载和显示图片,即使是在加载大量图像的情况下,仍能得到较高的界面响应速度和流畅性。

3 总结

本文介绍了Android应用开发中最常用的ListView组件的基本工作原理,阐述了ListView组件在开发中的四种优化方法。有关ListView性能的两个因素是,在适配器的getView()方法中不要执行耗时的任务,也不要改行布局的尺寸。如果确需执行耗时操作,可借助线程或线程池的方式进行异步任务处理,或者采取预加载机制。尽管ListView的使用比较简单,但也存在局限性,比如修改数据时必须要调用notifyDataSetChanged()通知适配器,而且要实现比较复杂的动画效果时就显得有点力不从心。这种情况下,可以考虑使用功能更强的RecyclerView组件,当然其使用方法也更为灵活和复杂。

参考文献(References):

[1] 李新辉,邹绍芳.Android移动应用开发项目教程[M].人民邮电出版社,2014.

[2] 黄宏程,胡敏,陈如松.Android移动应用设计与开发[M].人民邮电出版社,2014.

[3] 杨丰盛.Android应用开发揭秘[M].机械工业出版社,2010.

[4]丁振凡,吴小元.Android系统ListView控件数据递增显示研究[J].智能计算机与应用,2014.4(2):49-53

[5] 王向辉,张国印,沈洁.Android应用程序开发[M]. 清华大学出版社,2010.

猜你喜欢

优化
超限高层建筑结构设计与优化思考
一道优化题的几何解法
由“形”启“数”优化运算——以2021年解析几何高考题为例
基于低碳物流的公路运输优化