1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Android进阶:ListView性能优化异步加载图片 使滑动效果流畅

Android进阶:ListView性能优化异步加载图片 使滑动效果流畅

时间:2024-05-01 07:29:42

相关推荐

Android进阶:ListView性能优化异步加载图片 使滑动效果流畅

ListView是一种可以显示一系列项目并能进行滚动显示的 View,每一行的Item可能包含复杂的结构,可能会从网络上获取icon等的一些图标信息,就现在的网络速度要想保持ListView运行的很好滚动流畅是做不到的

所以这里就需要把这些信息利用多线程实现异步加载

实现这样功能的类

[java]view plaincopy publicclassAsyncImageLoader{privateHashMap<String,SoftReference<Drawable>>imageCache;publicAsyncImageLoader(){imageCache=newHashMap<String,SoftReference<Drawable>>();}publicDrawableloadDrawable(finalStringimageUrl,finalImageCallbackimageCallback){if(imageCache.containsKey(imageUrl)){SoftReference<Drawable>softReference=imageCache.get(imageUrl);Drawabledrawable=softReference.get();if(drawable!=null){returndrawable;}}finalHandlerhandler=newHandler(){@OverridepublicvoidhandleMessage(Messagemessage){imageCallback.imageLoaded((Drawable)message.obj,imageUrl);}};newThread(){@Overridepublicvoidrun(){Drawabledrawable=loadImageFromUrl(imageUrl);imageCache.put(imageUrl,newSoftReference<Drawable>(drawable));Messagemessage=handler.obtainMessage(0,drawable);handler.sendMessage(message);}}.start();returnnull;}publicstaticDrawableloadImageFromUrl(Stringurl){//...}publicinterfaceImageCallback{publicvoidimageLoaded(DrawableimageDrawable,StringimageUrl);}}

注意这里使用了 SoftReference来缓存图片,允许 GC在需要的时候可以对缓存中的图片进行清理。它这样工作:

· 调用 loadDrawable(ImageUrl, imageCallback),传入一个匿名实现的 ImageCallback接口

· 如果图片在缓存中不存在的话,图片将从单一的线程中下载并在下载结束时通过 ImageCallback回调

· 如果图片确实存在于缓存中,就会马上返回,不会回调 ImageCallback

然后我们还可以根据09google I/0开发者大会提到的方式来继续优化Adapter 使用ViewHolder来减少一些比较费时的操作,譬如inflate XML 和 findViewById()等操作

[java]view plaincopy publicclassImageAndTextListAdapterextendsArrayAdapter<ImageAndText>{privateListViewlistView;privateAsyncImageLoaderasyncImageLoader;publicImageAndTextListAdapter(Activityactivity,List<ImageAndText>imageAndTexts,ListViewlistView){super(activity,0,imageAndTexts);this.listView=listView;asyncImageLoader=newAsyncImageLoader();}@OverridepublicViewgetView(intposition,ViewconvertView,ViewGroupparent){Activityactivity=(Activity)getContext();//InflatetheviewsfromXMLViewrowView=convertView;ViewCacheviewCache;if(rowView==null){LayoutInflaterinflater=activity.getLayoutInflater();rowView=inflater.inflate(R.layout.image_and_text_row,null);viewCache=newViewCache(rowView);rowView.setTag(viewCache);}else{viewCache=(ViewCache)rowView.getTag();}ImageAndTextimageAndText=getItem(position);//LoadtheimageandsetitontheImageViewStringimageUrl=imageAndText.getImageUrl();ImageViewimageView=viewCache.getImageView();imageView.setTag(imageUrl);DrawablecachedImage=asyncImageLoader.loadDrawable(imageUrl,newImageCallback(){publicvoidimageLoaded(DrawableimageDrawable,StringimageUrl){ImageViewimageViewByTag=(ImageView)listView.findViewWithTag(imageUrl);if(imageViewByTag!=null){imageViewByTag.setImageDrawable(imageDrawable);}}});imageView.setImageDrawable(cachedImage);//SetthetextontheTextViewTextViewtextView=viewCache.getTextView();textView.setText(imageAndText.getText());returnrowView;}}

这里我们没有加载完iamge之后直接设定到相应的ImageView上 ,而是通过Tag查找,这里我们重用的View 这里有个listView的引用来通过Tag查找 可见 CallBack的实现

[c-sharp]view plaincopy ImageViewimageViewByTag=(ImageView)listView.findViewWithTag(imageUrl);if(imageViewByTag!=null){imageViewByTag.setImageDrawable(imageDrawable);}

这里通过ViewCatch来减少了 findViewById的使用

[c-sharp]view plaincopy publicclassViewCache{privateViewbaseView;privateTextViewtextView;privateImageViewimageView;publicViewCache(ViewbaseView){this.baseView=baseView;}publicTextViewgetTextView(){if(textView==null){textView=(TextView)baseView.findViewById(R.id.text);}returntitleView;}publicImageViewgetImageView(){if(imageView==null){imageView=(ImageView)baseView.findViewById(R.id.image);}returnimageView;}}

总结:这里主要做了三点优化

在单一线程里加载图片 重用列表中行 缓存行中的 View

转自:/wanglong0537/article/details/6334005

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。