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;
- }
- }
运行结果: