在Android中经常性的会用到加载图片的问题,那么为了不阻塞主线程,我们首先要考虑异步操作,为了用户更好地体验我们还需要考虑对图片进行缓存。
对图片进行缓存首先要了解softreference<Bitmap>软存储机制,还有就是硬存储的方式在手机端一般就是SD卡的存储。
那么如果当我们进行图片异步加载的时候就需要考虑内存中是否有,如果内存中有的话直接从内存中取出,如果内存中没有的话,再从网上去下载。
判断内存中是否有图片要先从softreference中判断,如果没有就从SD卡中读取,如果两者都没有则从网上下载
ImgLoader.java
- package com.SQLiteTest;
- import java.io.FileInputStream;
- import java.lang.ref.SoftReference;
- import java.util.Map;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.Environment;
- public class PicManager {
- private Context context;
- private Map<String, SoftReference<Bitmap>> imgCache;
- private FileUtils fUtils=new FileUtils();
- /*
- * 构造函数
- */
- public PicManager(Context context,
- Map<String, SoftReference<Bitmap>> imgCache) {
- super();
- this.context = context;
- this.imgCache = imgCache;
- }
- /*
- * 先从缓存中读取,如果没有的话从文件读取
- */
- public Bitmap getFromCache(String url)
- {
- Bitmap bit=null;
- if(imgCache.containsKey(url))
- {
- synchronized (imgCache) {
- SoftReference<Bitmap> bitReference=imgCache.get(url);
- if(bitReference!=null)
- {
- bit=bitReference.get();
- }
- }
- }
- else {
- bit=getFromSDcard(url);
- imgCache.put(url, new SoftReference<Bitmap>(bit));
- }
- return bit;
- }
- private Bitmap getFromSDcard(String url)
- {
- Bitmap bitmap=null;
- String filename=fUtils.getFName(url);
- System.out.println("PicManager-->"+filename);
- String path=Environment.getExternalStorageDirectory()+"/";
- try {
- FileInputStream fis=context.openFileInput(path+"picture/"+filename);
- //FileInputStream fis=new FileInputStream(path+"picture"+filename);
- bitmap=BitmapFactory.decodeStream(fis);
- fis.close();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return bitmap;
- }
- }
PicManager.java
- package com.SQLiteTest;
- import java.lang.ref.SoftReference;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.Handler;
- public class ImgLoader {
- private Context context;
- final Map<String, SoftReference<Bitmap>> imgCache=
- new HashMap<String, SoftReference<Bitmap>>();
- public ImgLoader(Context context) {
- super();
- this.context = context;
- }
- private Handler mhandler=new Handler();
- private PicManager pm=new PicManager(context, imgCache);
- private FileUtils fuUtils=new FileUtils();
- private ExecutorService threadPool=Executors.newFixedThreadPool(5);
- private DownLoad dl=new DownLoad();
- public Bitmap loadImg(final String url,final ImgCallBack callBack)
- {
- Bitmap bitmap=null;
- try {
- bitmap=pm.getFromCache(url);
- System.out.println("ImgLoader--->执行??? ");
- if(bitmap==null)
- {
- System.out.println("ImgLoader--->什么时候执行");
- threadPool.submit(new Runnable() {
- @Override
- public void run() {
- // TODO Auto-generated method stub
- String fname=fuUtils.getFName(url);
- dl.download(url,"picture/", fname);
- final Bitmap bit=BitmapFactory.decodeStream(dl.getInput(url));
- //imgCache.put(url,new SoftReference<Bitmap>(bit));
- mhandler.post(new Runnable() {
- @Override
- public void run() {
- // TODO Auto-generated method stub
- callBack.refresh(bit);
- }
- });
- }
- });
- }
- } catch (Exception e) {
- // TODO: handle exception
- }
- return bitmap;
- }
- }
DownLoad.java
- package com.SQLiteTest;
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- public class DownLoad {
- public void download(String url,String path,String filename)
- {
- FileUtils fUtils=new FileUtils();
- InputStream input=null;
- if(!fUtils.isExist(filename))
- {
- try
- {
- input=getInput(url);
- System.out.println("DownLoad--->"+input);
- fUtils.write2SDCARD(path, filename, input);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- public InputStream getInput(String urlstr)
- {
- URL url=null;
- InputStream input=null;
- try {
- url = new URL(urlstr);
- HttpURLConnection hul=(HttpURLConnection)url.openConnection();
- input=hul.getInputStream();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return input;
- }
- }
FileUtilts.java
- package com.SQLiteTest;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.io.OutputStream;
- import android.os.Environment;
- public class FileUtils {
- private String SDPATH=Environment.getExternalStorageDirectory()+"/";
- public File creaPath(String path)
- {
- File file=new File(SDPATH+path);
- file.mkdir();
- return file;
- }
- public File creaFile(String fileName) throws Exception
- {
- File f=new File(SDPATH+fileName);
- f.createNewFile();
- return f;
- }
- public boolean isExist(String Filename)
- {
- File f=new File(SDPATH+Filename);
- return f.exists();
- }
- public void write2SDCARD(String path,String filename,InputStream input)
- {
- try {
- creaPath(path);
- File file =creaFile(path+filename);
- OutputStream output=new FileOutputStream(file);
- byte[] buffer=new byte[4*1024];
- int line=0;
- while((line=input.read(buffer))!=-1)
- {
- output.write(buffer,0, line);
- }
- output.flush();
- output.close();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- public String getFName(String url)
- {
- int start=url.lastIndexOf("/");
- String str=url.substring(start);
- return str;
- }
- }
ImgCallBack.java
这是个接口主要负责刷新Bitmap
- package com.SQLiteTest;
- import android.graphics.Bitmap;
- public interface ImgCallBack {
- public void refresh(Bitmap bitmap);
- }