Android圖片異步加載
import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.lang.ref.SoftReference; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.Map;import com.mosjoy.ad.MosJoyAdApplication; import com.mosjoy.ad.R; import com.mosjoy.ad.utils.FileCache; import com.mosjoy.ad.utils.ImageCache; import com.mosjoy.ad.utils.Utils;
import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Environment; import android.os.StatFs; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.ImageView;
/**
- 圖片異步加載工具類
@author zouyb / public class RemoteImageView extends ImageView {
/**
下載失敗最大重復次數 */ private static int MAX_FAILURES = 3;
/**
下載圖片網址 */ private String mUrl;
/**
當前下載成功圖片網址 */ private String mCurrentlyGrabbedUrl;
/**
下載失敗次數 */ private int mFailure;
/**
默認圖片資源id */ private Integer mDefaultImage;
/**
上下文 */ private Context mContext;
/**
文件操作 */ private FileCache fileCache;
private final static int MB = 1048576;
//圖片寬度 private int pwidth=-1; //圖片高度 private int pheight=-1; //是否顯示默認圖片 private boolean isShowDefault=false; public RemoteImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mContext = context; init(); }
public RemoteImageView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; init(); }
public RemoteImageView(Context context) { super(context); mContext = context; init(); }
/**
Sharable code between constructors */ private void init() { fileCache = new FileCache(mContext); }
public void setImageUrl(String url) { System.out.println("width="+pwidth+",height="+pheight); System.out.println("url="+url); if(("").equals(url) || url == null||url.contains("null")){
if(isShowDefault){ setImageResource(R.drawable.default_image); }else{ setVisibility(View.GONE); } return;
} setVisibility(View.VISIBLE); url = url.replace("\", "/"); mUrl = url; MosJoyAdApplication instance = MosJoyAdApplication.getInstance(); ImageCache imageCache = instance.getImageCache(); if (imageCache.isCached(mUrl)) {
// 圖片在緩存中 this.setImageBitmap(imageCache.get(mUrl).get()); Log.e(MosJoyAdApplication.TAG, "從內存加載圖片 " + url);
} else {
File f = new File(mUrl); Bitmap b = decodeFile(f); if(b != null){ //從內存卡加載 this.setImageBitmap(b); imageCache.put(mUrl,new SoftReference<Bitmap>(b)); Log.e(MosJoyAdApplication.TAG, "從本地加載圖片 " + url); }else{ //防止重復下載 //if(YYQMusicApplication.getInstance().getDownLoadImageList().contains(mUrl)) return; //下載圖片 Log.e(MosJoyAdApplication.TAG, "從網絡下載圖片 " + url); Map<String,Object> map = new HashMap<String,Object>(); map.put("url", mUrl); map.put("file", f); try{ new DownloadTask().execute(map); }catch(Exception e){} }
}
}
public void setDefaultImage(Integer resid) { mDefaultImage = resid; }
private void loadDefaultImage() { if (mDefaultImage != null)
setImageResource(mDefaultImage);
}
class DownloadTask extends AsyncTask<Map<String, Object>,Void, Bitmap>{
private String mTaskUrl; private File f;
@Override public void onPreExecute() {
loadDefaultImage(); super.onPreExecute();
}
@Override protected Bitmap doInBackground(Map<String, Object>... params) {
mTaskUrl = params[0].get("url").toString(); //YYQMusicApplication.getInstance().getDownLoadImageList().add(mTaskUrl); f = (File) params[0].get("file"); try { Bitmap bitmap=null; URL imageUrl = new URL(mTaskUrl); HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection(); conn.setConnectTimeout(30000); conn.setReadTimeout(30000); InputStream is=conn.getInputStream(); OutputStream os = new FileOutputStream(f); Utils.CopyStream(is, os); os.close(); bitmap = decodeFile(f); return bitmap; } catch(FileNotFoundException fileNotFoundException){ fileNotFoundException.printStackTrace(); return null; } catch (Exception ex){ ex.printStackTrace(); } return null;
}
@Override public void onPostExecute(Bitmap b) {
super.onPostExecute(b); if(b == null){ //下載失敗,繼續下載 //RemoteImageView.this.setImageUrl(mTaskUrl); }else{ //下載成功 MosJoyAdApplication.getInstance().getImageCache().put(mTaskUrl, new SoftReference<Bitmap>(b)); RemoteImageView.this.setImageBitmap(b); mCurrentlyGrabbedUrl = mTaskUrl; }
}
};
/**
- 解碼圖片
- @param f
@return */ private Bitmap decodeFile(File f) { if(!f.exists()){
return null;
} if(pwidth>0&&pheight>0){
System.out.println("加載縮略圖"); return decodeFile(f, pwidth, pheight);
} try {
BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 1; return BitmapFactory.decodeFile(f.getAbsolutePath(), options);
} catch (Exception e) { } return null; }
private int freeSpaceOnSd() { StatFs stat = new StatFs(Environment.getExternalStorageDirectory()
.getPath());
double sdFreeMB = ((double) stat.getAvailableBlocks() * (double) stat
.getBlockSize()) / MB;
return (int) sdFreeMB; }
private Bitmap decodeFile(File file,int width,int height){ BitmapFactory.Options options=new BitmapFactory.Options(); int scale=1; if(width>0||height>0){
//設置次參數為true,解碼時返回的Bitmap為空,不分配內存 options.inJustDecodeBounds=true; BitmapFactory.decodeFile(file.getAbsolutePath(), options); //得到原始圖片的寬度和高度 int outWidth=options.outWidth; int outHeight=options.outHeight; while(true){ if((width>0&&outWidth/2<width)||(height>0&&outHeight/2<height)){ break; } outWidth/=2; outHeight/=2; scale*=2; }
} //縮放比例為1/scale options.inSampleSize=scale; options.inJustDecodeBounds=false; //處理之后,加載進內存的就是圖片的縮略圖 return BitmapFactory.decodeFile(file.getAbsolutePath(), options); }
public void setPwidth(int pwidth) { this.pwidth = pwidth; }
public void setPheight(int pheight) { this.pheight = pheight; }
public void setShowDefault(boolean isShowDefault) { this.isShowDefault = isShowDefault; }
}</pre>