一級緩沖:也就是通常所說的記憶體緩沖,android采用LruCache實作
二級緩沖:就是本地硬碟緩沖,android 采用DiskLruCache實作(等待下次學習,再分享)
注:Android自帶的緩存類LruCache或LruDiskCache
package czg.czgnewsasyn;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.LruCache;
import android.widget.ImageView;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Created by Administrator on 2016/5/28.
*/
public class ImageLoader {
private ImageView mImageView;
private String mUrl;
//android使用緩沖 lru近期使用最少算法 第一個參數是鍵值對,第二個參數是類型
private LruCache<String ,Bitmap> mCaches; //第一個key參數就是url,第二個參數object就bitmap
public ImageLoader() {
//擷取最大可用記憶體
int maxMemory= (int) Runtime.getRuntime().maxMemory();
int cacheSize=maxMemory /4;
mCaches=new LruCache<String ,Bitmap>(cacheSize){
@Override
protected int sizeOf(String key, Bitmap value) {
//在每次存入緩沖的時候調用
//return super.sizeOf(key, value);
return value.getByteCount();
}
};
}
//增加到緩沖
public void addBitmapToCache(String url,Bitmap bitmap){
if (getBitmapFromCache(url)==null){
mCaches.put(url,bitmap);
}
}
//從緩沖中擷取資料
public Bitmap getBitmapFromCache(String url){
return mCaches.get(url);
}
/**
* 這個handler配合showImageByThread更新ImageView
*/
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//當image的Tag與我們的url相同所示,我們才去更新imageView,進而避免了緩沖的圖檔,對正确的圖檔産生的影響
if (mImageView.getTag().equals(mUrl)){
mImageView.setImageBitmap((Bitmap) msg.obj);
}
}
};
/**
* 建立一個線程去解析url對于的Btimap圖檔對象,并把bitmap以消息的形式發送給主線程的Handler,并由handler設定給ImageView更新到主線程的UI上去
* @param imageView
* @param url
*/
public void showImageByThread(ImageView imageView, final String url){
mImageView = imageView;
mUrl=url;
new Thread(){
@Override
public void run() {
super.run();
Bitmap bitmap = getBitmapFromURL(url);
//通過message傳遞bitmap給handler,,通知handler去更新ImageView對象
Message message = Message.obtain();
message.obj = bitmap;
mHandler.sendMessage(message);
}
}.start();
}
/**
* 通過圖檔的url位址解析為Bitmap對象
* @param urlString
* @return
*/
public Bitmap getBitmapFromURL(String urlString){
Bitmap bitmap;
InputStream is=null;
try {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
is = new BufferedInputStream(connection.getInputStream());
bitmap = BitmapFactory.decodeStream(is);
connection.disconnect();
// try {
// Thread.sleep(1000); //模拟網絡不好的情況
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
return bitmap;
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
public void showImageByAsyncTask(ImageView imageView,String url){
//檢查緩沖中是否有這張圖檔,如果有則直接從緩沖中擷取圖檔,否則,啟用異步下載下傳圖檔
Bitmap bitmap = getBitmapFromCache(url);
if (bitmap==null){
new NewsAsyncTask(imageView,url).execute(url);
}else {
imageView.setImageBitmap(bitmap);
}
}
//第一個參數是Url,中間過程不需要則采用Void,最後傳回是一個Bitmap
private class NewsAsyncTask extends AsyncTask<String,Void,Bitmap>{
private ImageView mImageView;
private String mUrl;
public NewsAsyncTask(ImageView imageView,String url) {
this.mImageView = imageView;
this.mUrl=url;
}
@Override
protected Bitmap doInBackground(String... params) {
String url = params[0];
//從網絡擷取圖檔
Bitmap bitmap = getBitmapFromURL(url);
if (bitmap!=null){
//将不在緩沖中的圖檔,加入緩沖
addBitmapToCache(url,bitmap);
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if (mImageView.getTag().equals(mUrl)){
mImageView.setImageBitmap(bitmap);
}
}
}
}