LoadRemoteImage
公有成员方法setRemoteImageListener用于监听远端图片
传入两个参数:String url 图片URL地址 OnRemoteImageListener listener OnRemoteImageListener接口
线程Runnable接口处理流程图:
package lizhen.dg;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
/**
* 遠端圖片類
* */
public class LoadRemoteImage {
private ExecutorService pool; //線程池
private final int MESSAGE_OK = 1; //遠端圖片獲取成功消息
private final int MESSAGE_ERROR = -1; //遠端圖片獲取錯誤消息
private ImageBuffer imageBuffer; //圖片緩存
/**
* 構造函數
* 執行初始化操作
* */
public LoadRemoteImage() {
pool = Executors.newCachedThreadPool();
imageBuffer = new ImageBuffer();
}
/**
* 設置遠端圖片事件監聽器
* @param url 圖像URL地址
* @param listener 遠端圖片監聽器
* */
public void setRemoteImageListener(final String url, final OnRemoteImageListener listener) {
/*
* 遠端圖片消息處理Handler
* */
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int what = msg.what;
switch(what) {
case MESSAGE_OK : //成功
listener.onRemoteImage((Bitmap) msg.obj); //調用onRemoteImage回調方法
break;
case MESSAGE_ERROR : //錯誤
listener.onError((String) msg.obj); 調用onError回調方法
break;
}
}
};
/*
* 向線程池中添加新任務
* 下載給定URL地址圖片
* */
pool.execute(new Runnable() {
@Override
public void run() {
try {
Bitmap image = null;
/*
* 如果圖片緩存中沒有該圖片,則下載放入緩存中
* */
if((image = imageBuffer.get(url)) == null) {
byte[] resource = httpRequestByteArray(url); //HTTP請求圖片字節數據
image = optimizeBitmap(resource, 100, 100); //獲得優化的圖像
imageBuffer.put(url, image);
}
handler.sendMessage(handler.obtainMessage(MESSAGE_OK, image)); //遠端圖像下載成功
} catch (Exception e) {
/*
* 異常處理
* */
handler.sendMessage(handler.obtainMessage(MESSAGE_ERROR, e.getMessage()));
return;
}
}
});
}
/**
* 使用HTTP GET方式請求
* @param url URL地址
* @return HttpEntiry對象
* @throws Exception
* */
private byte[] httpRequestByteArray(String url) throws Exception {
byte[] result = null;
HttpGet httpGet = new HttpGet(url);
HttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse;
httpResponse = httpClient.execute(httpGet);
int httpStatusCode = httpResponse.getStatusLine().getStatusCode();
/*
* 判斷HTTP狀態碼是否為200
* */
if(httpStatusCode == HttpStatus.SC_OK) {
result = EntityUtils.toByteArray(httpResponse.getEntity());
} else {
throw new Exception("HTTP: "+httpStatusCode);
}
return result;
}
private Bitmap optimizeBitmap(byte[] resource, int maxWidth, int maxHeight) {
Bitmap result = null;
int length = resource.length;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
result = BitmapFactory.decodeByteArray(resource, 0, length, options);
int widthRatio = (int) Math.ceil(options.outWidth / maxWidth);
int heightRatio = (int) Math.ceil(options.outHeight / maxHeight);
if(widthRatio > 1 || heightRatio > 1) {
if(widthRatio > heightRatio) {
options.inSampleSize = widthRatio;
} else {
options.inSampleSize = heightRatio;
}
}
options.inJustDecodeBounds = false;
result = BitmapFactory.decodeByteArray(resource, 0, length, options);
return result;
}
/**
* 遠端圖片監聽器
* */
public interface OnRemoteImageListener {
/**
* 遠端圖片處理
* @param image 位圖圖片
* */
void onRemoteImage(Bitmap image);
/**
* 錯誤處理
* @param error 錯誤信息
* */
void onError(String error);
}
}
ImageBuffer 图片缓存
String键->SoftReference<Bitmap>值储存缓存图片
SoftReference软引用
在内存吃紧抛出“OutOfMemory”异常之前,会被JVM回收,此时调用get方法会返回null
package lizhen.dg;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
import android.graphics.Bitmap;
/**
* 圖片緩存類
* */
public class ImageBuffer {
private Map<String, SoftReference<Bitmap>> buffer = new HashMap<String, SoftReference<Bitmap>>(); //圖片緩存
/**
* 將圖片放進緩存中
* @param key 鍵值
* @param image Bitmap位圖
* */
public void put(String key, Bitmap image) {
SoftReference<Bitmap> reference = new SoftReference<Bitmap>(image);
synchronized(buffer) {
buffer.put(key, reference);
}
}
/**
* 從緩存中取得圖片
* @param key 鍵值
* @return Bitmap位圖
* */
public Bitmap get(String key) {
Bitmap result = null;
synchronized(buffer) {
if(buffer.containsKey(key)) {
result = buffer.get(key).get();
}
}
return result;
}
}
ListActivity
ListView列表异步加载远端图片
package lizhen.dg;
import android.app.ListActivity;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.Toast;
public class Main extends ListActivity {
private String data[] = {
"http://192.168.211.86/pic/0.jpg"
, "http://192.168.211.86/pic/1.jpg"
, "http://192.168.211.86/pic/2.jpg"
, "http://192.168.211.86/pic/3.jpg"
, "http://192.168.211.86/pic/4.jpg"
, "http://192.168.211.86/pic/5.jpg"
, "http://192.168.211.86/pic/6.jpg"
, "http://192.168.211.86/pic/7.jpg"
, "http://192.168.211.86/pic/8.jpg"
, "http://192.168.211.86/pic/9.jpg"
, "http://192.168.211.86/pic/10.jpg"
, "http://192.168.211.86/pic/11.jpg"
, "http://192.168.211.86/pic/12.jpg" //錯誤的圖片地址
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setListAdapter(new MyListAdapter(this, data));
}
private class MyListAdapter extends BaseAdapter {
private Context context;
private String[] data;
private LoadRemoteImage remoteImage;
public MyListAdapter(Context context, String[] data) {
this.context = context;
this.data = data;
remoteImage = new LoadRemoteImage();
}
@Override
public int getCount() {
return data.length;
}
@Override
public Object getItem(int position) {
return data[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder = null;
if(convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.item, parent, false);
holder = new Holder(convertView);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
final ImageView icon = holder.getIcon();
icon.setImageResource(R.drawable.icon);
remoteImage.setRemoteImageListener((String) getItem(position), new LoadRemoteImage.OnRemoteImageListener() {
@Override
public void onError(String error) {
Toast.makeText(context, error, Toast.LENGTH_LONG).show();
}
@Override
public void onRemoteImage(Bitmap image) {
icon.setImageBitmap(image);
}
});
holder.getName().setText((String) getItem(position));
return convertView;
}
}
}
package lizhen.dg;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
public class Holder {
private View parentView;
private ImageView iconImageView;
private TextView labelTextView;
public Holder(View view) {
this.parentView = view;
}
public ImageView getIcon() {
if(iconImageView == null) {
iconImageView = (ImageView) parentView.findViewById(R.id.item_IconImageView);
}
return iconImageView;
}
public TextView getName() {
if(labelTextView == null) {
labelTextView = (TextView) parentView.findViewById(R.id.item_NameTextView);
}
return labelTextView;
}
}
运行结果: