- package cn.jd3g.utils;
- 002
- 003 import java.lang.ref.SoftReference;
- 004 import java.util.HashMap;
- 005 import java.util.LinkedHashMap;
- 006 import java.util.Map.Entry;
- 007
- 008 import android.graphics.Bitmap;
- 009 import android.os.Handler;
- 010 import android.util.Log;
- 011 import android.widget.ImageView;
- 012
- 013
-
- 019 public final class AsynImageLoader {
- 020
- 021 private LoaderThread thread;
- 022 private HashMap> imageCache;
- 023 private Handler handler;
- 024
- 025 public AsynImageLoader(Handler handler) {
- 026 imageCache = new HashMap>();
- 027 this.handler = handler;
- 028 }
- 029
- 030
-
- 038 public void loadBitmap(ImageView imageView, Bitmap defaultBitmap) {
- 039
- 040 String url = (String) imageView.getTag();
- 041 if (imageCache.containsKey(url)) {
- 042 SoftReference softReference = imageCache.get(url);
- 043 Bitmap bitmap = softReference.get();
- 044 if (bitmap != null) {
- 045 imageView.setImageBitmap(bitmap);
- 046 return;
- 047 } else {
- 048 Log.e("TAG", "cache bitmap is null");
- 049 imageCache.remove(url);
- 050 }
- 051 }
- 052 imageView.setImageBitmap(defaultBitmap);
- 053 if (thread == null) {
- 054 thread = new LoaderThread(imageView, url);
- 055 thread.start();
- 056 } else {
- 057 thread.load(imageView, url);
- 058 }
- 059
- 060 }
- 061
- 062
-
- 065 public void releaseBitmapCache() {
- 066 if (imageCache != null) {
- 067 for (Entry> entry : imageCache.entrySet()) {
- 068 Bitmap bitmap = entry.getValue().get();
- 069 if (bitmap != null) {
- 070 bitmap.recycle();
- 071 }
- 072 }
- 073 imageCache.clear();
- 074 }
- 075 }
- 076
- 077
-
- 080 private class LoaderThread extends Thread {
- 081
- 082 LinkedHashMap mTaskMap;
- 083 private boolean mIsWait;
- 084
- 085 public LoaderThread(ImageView imageView, String url) {
- 086 mTaskMap = new LinkedHashMap();
- 087 mTaskMap.put(url, imageView);
- 088 }
- 089
- 090
-
- 095 public void load(ImageView imageView, String url) {
- 096 mTaskMap.remove(imageView);
- 097 mTaskMap.put(url, imageView);
- 098 if (mIsWait) {
- 099 synchronized (this) {
- 100 this.notify();
- 101 }
- 102 }
- 103 }
- 104
- 105 @Override
- 106 public void run() {
- 107 while (mTaskMap.size() > 0) {
- 108 mIsWait = false;
- 109 final String url = mTaskMap.keySet().iterator().next();
- 110 final ImageView imageView = mTaskMap.remove(url);
- 111 if (imageView.getTag() == url) {
- 112 final Bitmap bitmap = MyConnection.getBitmapByUrl(url);
- 113 try {
- 114 Thread.sleep(1000);
- 115 } catch (InterruptedException e1) {
- 116 e1.printStackTrace();
- 117 }
- 118
- 119 imageCache.put(url, new SoftReference(bitmap));
- 120 if (url == imageView.getTag()) {
- 121 handler.post(new Runnable() {
- 122 @Override
- 123 public void run() {
- 124 imageView.setImageBitmap(bitmap);
- 125 }
- 126 });
- 127 }
- 128 }
- 129 if (mTaskMap.isEmpty()) {
- 130 try {
- 131 mIsWait = true;
- 132 synchronized (this) {
- 133 this.wait();
- 134 }
- 135 } catch (InterruptedException e) {
- 136 e.printStackTrace();
- 137 }
- 138 }
- 139 }
- 140 }
- 141 }
- 142 }
- 查看源码打印?01 private class ProductListAdapter extends BaseAdapter {
- 02
- 03 private AsynImageLoader mImageAsynLoader;
- 04
- 05 public ProductListAdapter() {
- 06 mImageAsynLoader = new AsynImageLoader(mHandler);
- 07 }
- 08
- 09 @Override
- 10 public int getCount() {
- 11 int size = Math.min(mLastItemViewIndex + 1, mDataList.size());
- 12 mLastItemViewIndex = size - 1;
- 13 return size;
- 14 }
- 15
- 16 @Override
- 17 public Object getItem(int position) {
- 18 return mDataList.get(position);
- 19 }
- 20
- 21 @Override
- 22 public long getItemId(int position) {
- 23 return position;
- 24 }
- 25
- 26 @Override
- 27 public View getView(int position, View convertView, ViewGroup parent) {
- 28 if (convertView == null) {
- 29 convertView = getLayoutInflater().inflate(R.layout.product_list_item,
- 30 null);
- 31 }
- 32 ImageView imageView = (ImageView) convertView
- 33 .findViewById(R.id.iv_item_product_image);
- 34 Map map = mDataList.get(position);
- 35
- 36 imageView.setTag(map.get("product_pic_address"));
- 37 mImageAsynLoader.loadBitmap(imageView, mDefautBitmap);
- 38 return convertView;
- 39 }
- 40 }
package cn.jd3g.utils;
002
003 import java.lang.ref.SoftReference;
004 import java.util.HashMap;
005 import java.util.LinkedHashMap;
006 import java.util.Map.Entry;
007
008 import android.graphics.Bitmap;
009 import android.os.Handler;
010 import android.util.Log;
011 import android.widget.ImageView;
012
013 /**
014 * 利用多线程异步加载图片并更新视图
015 *
016 * @author xfzhang
017 *
018 */
019 public final class AsynImageLoader {
020
021 private LoaderThread thread;// 加载图片并发消息通知更新界面的线程
022 private HashMap
> imageCache;// 图片对象缓存,key:图片的url
023 private Handler handler;// 界面Activity的Handler对象
024
025 public AsynImageLoader(Handler handler) {
026 imageCache = new HashMap>();
027 this.handler = handler;
028 }
029
030 /**
031 * 加载图片前显示到指定的ImageView中,图片的url保存在视图对象的Tag中
032 *
033 * @param imageView
034 * 要显示图片的视图
035 * @param defaultBitmap
036 * 加载需要显示的提示正在加载的默认图片对象
037 */
038 public void loadBitmap(ImageView imageView, Bitmap defaultBitmap) {
039 // 图片所对应的url,这个值在加载图片过程中很可能会被改变
040 String url = (String) imageView.getTag();
041 if (imageCache.containsKey(url)) {// 判断缓存中是否有
042 SoftReference softReference = imageCache.get(url);
043 Bitmap bitmap = softReference.get();
044 if (bitmap != null) {// 如果图片对象不为空,则可挂接更新视图,并返回
045 imageView.setImageBitmap(bitmap);
046 return;
047 } else {// 如果为空,需要将其从缓存中删除(其bitmap对象已被回收释放,需要重新加载)
048 Log.e("TAG", "cache bitmap is null");
049 imageCache.remove(url);
050 }
051 }
052 imageView.setImageBitmap(defaultBitmap);// 先显示一个提示正在加载的图片
053 if (thread == null) {// 加载线程不存在,线程还未启动,需要新建线程并启动
054 thread = new LoaderThread(imageView, url);
055 thread.start();
056 } else {// 如果存在,就调用线程对象去加载
057 thread.load(imageView, url);
058 }
059
060 }
061
062 /**
063 * 释放缓存中所有的Bitmap对象,并将缓存清空
064 */
065 public void releaseBitmapCache() {
066 if (imageCache != null) {
067 for (Entry> entry : imageCache.entrySet()) {
068 Bitmap bitmap = entry.getValue().get();
069 if (bitmap != null) {
070 bitmap.recycle();// 释放bitmap对象
071 }
072 }
073 imageCache.clear();
074 }
075 }
076
077 /**
078 * 加载图片并显示的线程
079 */
080 private class LoaderThread extends Thread {
081
082 LinkedHashMap mTaskMap;// 需要加载图片并显示的图片视图对象任务链
083 private boolean mIsWait;// 标识是线程是否处于等待状态
084
085 public LoaderThread(ImageView imageView, String url) {
086 mTaskMap = new LinkedHashMap();
087 mTaskMap.put(url, imageView);
088 }
089
090 /**
091 * 处理某个视图的更新显示
092 *
093 * @param imageView
094 */
095 public void load(ImageView imageView, String url) {
096 mTaskMap.remove(imageView);// 任务链中可能有,得先删除
097 mTaskMap.put(url, imageView);// 将其添加到任务中
098 if (mIsWait) {// 如果线程此时处于等待得唤醒线程去处理任务队列中待处理的任务
099 synchronized (this) {// 调用对象的notify()时必须同步
100 this.notify();
101 }
102 }
103 }
104
105 @Override
106 public void run() {
107 while (mTaskMap.size() > 0) {// 当队列中有数据时线程就要一直运行,一旦进入就要保证其不会跳出循环
108 mIsWait = false;
109 final String url = mTaskMap.keySet().iterator().next();
110 final ImageView imageView = mTaskMap.remove(url);
111 if (imageView.getTag() == url) {// 判断视图有没有复用(一旦ImageView被复用,其tag值就会修改变)
112 final Bitmap bitmap = MyConnection.getBitmapByUrl(url);// 此方法应该是从网络或sd卡中加载
113 try {
114 Thread.sleep(1000);// 模拟网络加载数据时间
115 } catch (InterruptedException e1) {
116 e1.printStackTrace();
117 }
118 // 将加载的图片放入缓存map中
119 imageCache.put(url, new SoftReference(bitmap));
120 if (url == imageView.getTag()) {// 再次判断视图有没有复用
121 handler.post(new Runnable() {// 通过消息机制在主线程中更新UI
122 @Override
123 public void run() {
124 imageView.setImageBitmap(bitmap);
125 }
126 });
127 }
128 }
129 if (mTaskMap.isEmpty()) {// 当任务队列中没有待处理的任务时,线程进入等待状态
130 try {
131 mIsWait = true;// 标识线程的状态,必须在wait()方法之前
132 synchronized (this) {
133 this.wait();// 保用线程进入等待状态,直到有新的任务被加入时通知唤醒
134 }
135 } catch (InterruptedException e) {
136 e.printStackTrace();
137 }
138 }
139 }
140 }
141 }
142 }
查看源码打印?01 private class ProductListAdapter extends BaseAdapter {
02
03 private AsynImageLoader mImageAsynLoader;
04
05 public ProductListAdapter() {
06 mImageAsynLoader = new AsynImageLoader(mHandler);
07 }
08
09 @Override
10 public int getCount() {
11 int size = Math.min(mLastItemViewIndex + 1, mDataList.size());
12 mLastItemViewIndex = size - 1;
13 return size;
14 }
15
16 @Override
17 public Object getItem(int position) {
18 return mDataList.get(position);
19 }
20
21 @Override
22 public long getItemId(int position) {
23 return position;
24 }
25
26 @Override
27 public View getView(int position, View convertView, ViewGroup parent) {
28 if (convertView == null) {
29 convertView = getLayoutInflater().inflate(R.layout.product_list_item,
30 null);
31 }
32 ImageView imageView = (ImageView) convertView
33 .findViewById(R.id.iv_item_product_image);
34 Map map = mDataList.get(position);
35 //存放图片所对应的url
36 imageView.setTag(map.get("product_pic_address"));
37 mImageAsynLoader.loadBitmap(imageView, mDefautBitmap);
38 return convertView;
39 }
40 }
阅读(952) | 评论(0) | 转发(0) |