圖片的三級緩存
何爲圖片的三級緩存?
- 內存緩存(優先加載,加載速度最快,不耗費流量)
- 本地緩存(次優先加載,加載速度稍塊,不耗費流量)
- 網絡緩存(最後加載,加載速度最慢,耗費流量)
內存緩存
package bitmap;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
//內存緩存
public class MemoryCacheUtils {
private LruCache<String, Bitmap>mMemoryCacheUtils;
public MemoryCacheUtils(){
long maxMemory=Runtime.getRuntime().maxMemory()/8; //模擬器默認16M
mMemoryCacheUtils=new LruCache<String, Bitmap>((int) maxMemory){
@Override
protected int sizeOf(String key, Bitmap value) {
int byteCount=value.getRowBytes()*value.getHeight();
return byteCount;
}
};
}
//從內存讀
public Bitmap getBitmapFromMemory(String url){
return mMemoryCacheUtils.get(url) ;
}
//寫入內存
public void setBitmapToMemory(String url,Bitmap bitmap){
mMemoryCacheUtils.put(url,bitmap);
}
}
本地緩存
package bitmap;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.Environment;
//本地緩存
public class LocalCacheUtils {
public static final String CACHE_PATH=Environment.
getExternalStorageDirectory().getAbsolutePath()+"/getPhoto";
//從本地sdcard讀取圖片
public Bitmap getBitmapFromLocal(String url) {
try {
String fileName = MD5Encoder.encode(url);
File file=new File(CACHE_PATH,fileName);
if(file.exists()){
Bitmap bitmap=BitmapFactory.decodeStream(new FileInputStream(file));
return bitmap;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
//向sdcard寫圖片
public void setBitmapToLocal(String url,Bitmap bitmap){
try {
String fileName=MD5Encoder.encode(url);
File file=new File(CACHE_PATH,fileName);
File parentFile=file.getParentFile();
if(!parentFile.exists()){ //如果文件夾不存在
parentFile.mkdirs();
}
//將圖片保存到本地
bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream(file));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
網絡緩存
package bitmap;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import com.lidroid.xutils.bitmap.callback.BitmapLoadFrom;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;
//網絡緩存
public class NetCacheUtils {
LocalCacheUtils mLocalCacheUtils;
MemoryCacheUtils mMemoryCacheUtils;
public NetCacheUtils(LocalCacheUtils mLocalCacheUtils,MemoryCacheUtils mMemoryCacheUtils) {
this.mLocalCacheUtils=mLocalCacheUtils;
this.mMemoryCacheUtils=mMemoryCacheUtils;
}
//從網絡下載圖片
public void getBitmapFromNet(ImageView ivPic, String url) {
new BitmapTask().execute(ivPic,url); //啓動AsyncTask
}
//Handler和線程池的封裝
//第一個泛型:參數類型 第二個泛型:更新進度的泛型,第三個泛型:onPostExecute的返回結果
class BitmapTask extends AsyncTask<Object,Void,Bitmap>{
private ImageView ivPic;
private String url;
/**
* 後臺耗時方法在此執行, 子線程
*/
@Override
protected Bitmap doInBackground(Object... params) {
ivPic=(ImageView)params[0];
url=(String)params[1];
ivPic.setTag(url); //將url和imageView綁定
return downloadBitmap(url);
}
//更新進度,主線程
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
/**
* 耗時方法結束後,執行該方法, 主線程
*/
@Override
protected void onPostExecute(Bitmap result) {
if(result!=null){
String bindUrl=(String) ivPic.getTag();
if(url.equals(bindUrl)){ //確保圖片給了正確的Imageview
ivPic.setImageBitmap(result);
mLocalCacheUtils.setBitmapToLocal(url, result); //將圖片保存到本地
mMemoryCacheUtils.setBitmapToMemory(url, result);//將圖片保存到內存
System.out.println("從網絡讀取了。。。");
}
}
}
}
//下載圖片
private Bitmap downloadBitmap(String url){
HttpURLConnection conn = null;
try {
conn=(HttpURLConnection) new URL(url).openConnection();
conn.setConnectTimeout(5000); //設置連接時間
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
conn.connect();
int responseCode=conn.getResponseCode();
if(responseCode==200){
InputStream inputStream=conn.getInputStream();
//圖片壓縮處理
BitmapFactory.Options option=new BitmapFactory.Options();
option.inSampleSize=2; //寬高都壓縮爲原來的二分之一,根據圖片要展示的大小來設置
option.inPreferredConfig=Bitmap.Config.RGB_565; //設置圖片格式
Bitmap bitmap=BitmapFactory.decodeStream(inputStream,null,option);
//Bitmap bitmap=BitmapFactory.decodeStream(inputStream);
return bitmap;
}
} catch (IOException e) {
e.printStackTrace();
}finally{
conn.disconnect();
}
return null;
}
}
使用方法
//聲明圖片加載工具類
private MyBitmapUtils utils;
public TopNewsAdapter() {
utils = new MyBitmapUtils();
}
然後在getView()方法中,使用工具類中的display()方法就可以了
//display(ImageView image,String url)
utils.display(image, banner.pic);