呂海洋 劉忠利 劉競男
【摘 要】Android系統(tǒng)開發(fā)是目前移動(dòng)互聯(lián)開發(fā)的主流系統(tǒng),相對(duì)于計(jì)算機(jī)開發(fā),其內(nèi)存小、屏幕小,所以,對(duì)應(yīng)用程序的性能有特別高的要求。ListView是android開發(fā)中最重要的控件之一,使用頻率特別高,幾乎每個(gè)項(xiàng)目中都需要使用ListView控件實(shí)現(xiàn)列表顯示,因此,提高ListView控件的性能對(duì)整個(gè)項(xiàng)目的質(zhì)量及用戶體驗(yàn)至關(guān)重要,本文分析了ListView控件的實(shí)現(xiàn)原理,著重對(duì)其性能進(jìn)行優(yōu)化。
【關(guān)鍵字】Android開發(fā) ListView 性能優(yōu)化
一、引言
ListView控件是Android控件中使用最廣泛的控件之一,在程序加載過程中,如果數(shù)據(jù)較大容易出現(xiàn)白屏,等待時(shí)間較長,占用較大內(nèi)存甚至出現(xiàn)ANR(Application Not Responding)異常等問題;如果應(yīng)用程序連接網(wǎng)絡(luò)會(huì)浪費(fèi)用戶流量。為了解決該控件中出現(xiàn)的一系列問題,提高ListView的性能進(jìn)行優(yōu)化。
二、ListView原理與分析
(一)LsitView顯示的基本原理
List控件如果要顯示數(shù)據(jù)需要具備以下元素:ListView列表控件,數(shù)據(jù)適配器,布局文件,數(shù)據(jù)。四者的關(guān)系如下圖1所示。其中,ListView是基本的顯示控件,以列表的形式顯示數(shù)據(jù)信息,XML布局文件定義了ListView控件中每個(gè)item項(xiàng)包含的控件及布局格式,數(shù)據(jù)可以是數(shù)組、List集合等,存放要顯示的TextView、ImageView等控件的數(shù)據(jù)信息,Adapter為適配器將數(shù)據(jù)按照xml布局文件的格式顯示在List控件之中。
(二)BaseAdapter的原理
BaseAdaper是基本數(shù)據(jù)適配器,將數(shù)據(jù)資源按照布局文件格式填充到ListView控件,其中有相應(yīng)的重寫方法,用于顯示每項(xiàng)內(nèi)容的是public void getView(int Position, View convertView,ViewGroup parent){ }
圖1 ListView應(yīng)用關(guān)系圖
在圖1中,數(shù)據(jù)和xml布局文件是已定義好的內(nèi)容,不可以改變。如果提高ListView的性能,只有對(duì)Adaper的優(yōu)化,重點(diǎn)是getView的設(shè)計(jì)。重點(diǎn)分析getView的設(shè)計(jì)中占用內(nèi)存的關(guān)鍵環(huán)節(jié)所在。
三、分析問題
造成數(shù)據(jù)加載時(shí)間較長以及占用內(nèi)存的主要問題是在getView方法中的兩項(xiàng)主要操作占用了系統(tǒng)內(nèi)存。第一,對(duì)于列表顯示的每一項(xiàng)內(nèi)容,都需要加載其布局文件(假設(shè)布局文件為item.xml)。即View view = Inflater.inflate(R.layout.item1,null);第二,對(duì)于每一項(xiàng)中的各種控件都需要進(jìn)行查找(假設(shè)只有TextView控件)。
基于以上兩點(diǎn),如果數(shù)據(jù)內(nèi)容較大會(huì)占用較大內(nèi)存,影響數(shù)據(jù)加載及顯示效果。
四、性能優(yōu)化方案
為了解決以上問題,可以采取以下優(yōu)化方案。
(一)利用convertView的復(fù)用,減少創(chuàng)建view的次數(shù)。
在ListView中,并不能顯示全部數(shù)據(jù),只是按照屏幕可以容納的最大項(xiàng)目顯示列表項(xiàng),對(duì)于每個(gè)顯示項(xiàng)都需要調(diào)用getView()方法?;瑒?dòng)過程中一定是有項(xiàng)進(jìn)入,有項(xiàng)目退出。退出的項(xiàng)將保存在convertView項(xiàng),因此新項(xiàng)目可以利用convertView,省略使用inflater方法加載布局文件。每次首先判斷convertView是否為空,如果空,我們創(chuàng)建新的convertView;如果不為空,直接利用convertView創(chuàng)建view。不用再次填充布局,能夠節(jié)省大量內(nèi)存,效率可以提高200%左右。
(二)創(chuàng)建ViewHolder類,減少findbyId的次數(shù)。
加入的每一項(xiàng),具有相同的控件。每個(gè)控件需要在布局文件中找到相應(yīng)的控件并為其設(shè)定內(nèi)容。為了減少每次加載一些都需要到布局文件中查找每個(gè)控件,可以定義一個(gè)Viewholder類,為每項(xiàng)創(chuàng)建一個(gè)holder對(duì)象,將所有控件保持在holder中,并且通過setTag標(biāo)簽進(jìn)行查找,減少查找控件的次數(shù),效率可以再提高50%。
(三)優(yōu)化代碼
1.Public View getView(int position, View convertView, ViewGroup parent) {
2.ViewHolder holder=null;
3.if(convertView==null){ //如果為空,需要填充布局文件
4.convertView=mInflater.inflate(R.layout.item1,null);
5.holder=new ViewHolder();
6.holder.textView=(TextView)convertView.findViewById(R.id.text);
7.convertView.setTag(holder);
8.}else {
9.Holder = (ViewHolder)convertView.getTag();
10.}
11.holder.textView.setText(mData.get(position));
12.return convertView;
13.}
14.}
15.Public class ViewHolder{
16.Public TextView textView;
17.}
五、結(jié)論
通過對(duì)ListView的優(yōu)化,可以有效的提高顯示效果及加載速度,同時(shí)提高用戶體驗(yàn)效果。如果進(jìn)行大量數(shù)據(jù)加載,可以對(duì)較大數(shù)據(jù)采取分頁方式加載,如果對(duì)于加載網(wǎng)絡(luò)資源,可以采取異步方式。
參考文獻(xiàn):
[1]關(guān)于ListView控件優(yōu)化方案的研究與實(shí)現(xiàn) ,Computer Era 2012,沈潔等.
[2]Donet框架控件ListView的排序研究,冶金自動(dòng)化 2008,衛(wèi)萬勇.