Android中ListView之性能提高

  • 引言
  • 方法
    • 复用convertView
      • 示例代码
      • 改进的地方
    • ViewHolder
      • 示例代码
      • 改进的地方
    • 数据分页加载
      • 示例代码
      • 改进的地方
    • 图片异步加载
      • 示例代码
      • 改进的地方
    • 图片适当压缩
      • 示例代码
      • 改进的地方
    • 优化ItemView层级
      • 方法
      • 工具
      • 注意
      • 示例图
  • 总结

引言

面试中可能常常被问到如何如何优化ListView的性能,收集了一些资料,做一下简单的总结。

方法

复用convertView

示例代码

public View getView(int position,View convertView,ViewGroup parent){
    if(convertView == null){
        //ToDo:第一次加载
        convertView=LayoutInflater.from(mContext).inflate(R.layout.layout_item.null);
    }else{
        //ToDo:其它时候加载 
    }
    //ToDo something;

    return convertView;
}

改进的地方

减少了ItemView从xml文件中反射的次数,提高View生成的速度

ViewHolder

示例代码

private class ViewHolder{
    View item1;
    View item2;
}
public View getView(int position,View convertView,ViewGroup parent){
    final ViewHolder viewHolder=null;
    if(convertView == null){
        convertView=LayoutInflater.from(mContext).inflate(R.layout.layout_item.null);
        viewHolder = new ViewHolder();
        viewHolder.item1=convertView.findViewById(R.id.item1);
        ViewHolder.item2=convertView.findViewById(R.id.item2);
        convertView.setTag(viewHolder);
    }else{
        viewHolder=(ViewHolder)convertView.getTag();
    }
    //Todo something;

    return convertView;
}

改进的地方

这样做可以有效的减少itemview中子view反射的次数。有效的降低生成View消耗的时间。

数据分页加载

示例代码

int pageSize = 10;//每页加载的数据
public boolean loadMore(){
    boolean isEnd = false;
    List<Object> objects = getDate(lastDateIndex,pageSize);//该函数用于加载数据,自行实现
    for(int i=0 ;i<objects.size();i++){
        sourceList.add(objects.get(i));//sourceList是列表数据
    }
    if(pageSize != objects.size()){
        isEnd=true;//返回的数量不足pageSize,说明数据加载完毕
    }
    adapter.notifyDataSetChanged(); //数据集变化后,通知adapter
    return isEnd;
}

改进的地方

数据分页加载后,每次加载的数据量很少,减少了系统等待的时间。

图片异步加载

示例代码

package picturegame.async;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;

public class AsyncImageLoader {

    public static final int Type_Local=0;
    public static final int Type_Network=1;

    final Handler handler = new Handler();
    /*图片缓存 */
    private HashMap<String, SoftReference<Bitmap>> imageCache;

    public AsyncImageLoader(){
        imageCache=new HashMap<String, SoftReference<Bitmap>>();
    }

    public interface ImageLoaderCallBack{
        public void onSuccess(Integer imageViewId, Bitmap bitmap);
        public void onError(Integer imageViewId);
    }

    public Bitmap loadImage(final int type,final Integer pos,final String imageUrl,final ImageLoaderCallBack callback){
        new Thread(){
            @Override
            public void run() {
                // TODO Auto-generated method stub
                loadBitmap(type,pos,imageUrl,callback);
            }
        }.start();
        return null;
    }

    public void loadBitmap(final int type,final Integer pos,final String imageUrl,final ImageLoaderCallBack callBack){
        if(imageCache.containsKey(imageUrl)){
            SoftReference<Bitmap> softReference=imageCache.get(imageUrl);
            final Bitmap bitmmap=softReference.get();
            if(bitmmap != null){
                handler.post(new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        callBack.onSuccess(pos, bitmmap);
                    }
                });
                return;
            }
        }
        final Bitmap bitmap;
        try {
            bitmap = loadBitmapFromUrl(imageUrl,type);

        if(bitmap !=null){
            imageCache.put(imageUrl, new SoftReference<Bitmap>(bitmap));
            handler.post(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    callBack.onSuccess(pos, bitmap);
                }
            });
        }else{
            handler.post(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    callBack.onError(pos);
                }
            });
        }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            handler.post(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    callBack.onError(pos);
                }
            });
            e.printStackTrace();
        }

    }

    public static Bitmap  loadBitmapFromUrl(String url,int type) throws IOException{
        switch(type){
        case Type_Local://加载本地图片
            return BitmapFactory.decodeFile(url);
        case Type_Network://加载网络图片
                URL sourceURL=new URL(url);
                InputStream is = (InputStream)sourceURL.getContent();
                Bitmap bitmap = BitmapFactory.decodeStream(is);
                is.close();
                return bitmap;
        }
        return null;
    }

}

//用法
asyncImageLoader.loadBitmap(AsyncImageLoader.Type_Local, position, sourceList.get(position), new AsyncImageLoader.ImageLoaderCallBack() {

            @Override
            public void onSuccess(Integer imageViewId, Bitmap bitmap) {
                // TODO Auto-generated method stub
                ImageView  iv= mPics[imageViewId];//传入需要显示图片的View
                iv.setImageBitmap(intBitmap(bitmap));
                //initImageView(iv, viewWidth, viewHeight);
            }

            @Override
            public void onError(Integer imageViewId) {
                // TODO Auto-generated method stub
                ImageView  iv= mPics[imageViewId];//传入需要显示图片的View
                iv.setBackgroundResource(R.drawable.image01);
            }
        });

改进的地方

图片加载是一个耗时的操作,异步加载,可以有效的提高用户体验。

图片适当压缩

示例代码

Matrix matrix = new Matrix();
float scale = 0.5;//缩放比例
matrix.postScale(scale,scale);
Bitmap newBitmap=Bitmap.creatBitmap(oldBitmap,0,0,oldBitmap.getWidth(),oldBitmap.getHeight,matrix,true);

改进的地方

图片是比较耗内存的资源,降低图片质量,可以提高应用程序的流畅度。

优化ItemView层级

方法

使用SDK中的工具Hierachyviewer工具查看ItemView的层级树,减少不必要的层级,可以有效提高View生成速度。

工具

运行Android–>tools–>hierachyviewer.bat

注意

先运行模拟器,再运行该工具,才可以在工具下看到目录树结构。

示例图

总结

我所了解的就这么多,欢迎大家补充。

你可能感兴趣的:(android,性能,ListView)