面试中可能常常被问到如何如何优化ListView的性能,收集了一些资料,做一下简单的总结。
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生成的速度
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);
图片是比较耗内存的资源,降低图片质量,可以提高应用程序的流畅度。
使用SDK中的工具Hierachyviewer工具查看ItemView的层级树,减少不必要的层级,可以有效提高View生成速度。
运行Android–>tools–>hierachyviewer.bat
先运行模拟器,再运行该工具,才可以在工具下看到目录树结构。
我所了解的就这么多,欢迎大家补充。