异步下载网络图片,并提供是否缓存至内存或外部文件的功能

异步加载类AsyncImageLoader

public void downloadImage(final String url, final ImageCallback callback);

public void downloadImage(final String url, final boolean cache2Memory, final ImageCallback callback);

public void setCache2File(boolean flag);

public void setCachedDir(String dir);

图片下载和缓存实现类LoaderImpl


1.AsyncImageLoader.java

package com.imagecache;import java.lang.ref.SoftReference;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import android.content.Context;import android.graphics.Bitmap;import android.os.Handler;import android.util.Log;public class AsyncImageLoader {//保存正在下载的图片URL集合,避免重复下载用private static HashSet<String> sDownloadingSet;//软引用内存缓存private static Map<String,SoftReference<Bitmap>> sImageCache; //图片三种获取方式管理者,网络URL获取、内存缓存获取、外部文件缓存获取private static LoaderImpl impl;//线程池相关private static ExecutorService sExecutorService;//通知UI线程图片获取ok时使用private Handler handler; /** * 异步加载图片完毕的回调接口 */public interface ImageCallback{/** * 回调函数 * @param bitmap: may be null! * @param imageUrl  */public void onImageLoaded(Bitmap bitmap, String imageUrl);}static{sDownloadingSet = new HashSet<String>();sImageCache = new HashMap<String,SoftReference<Bitmap>>();impl = new LoaderImpl(sImageCache);}public AsyncImageLoader(Context context){handler = new Handler();startThreadPoolIfNecessary();String defaultDir = context.getCacheDir().getAbsolutePath();setCachedDir(defaultDir);}/** * 是否缓存图片至/data/data/package/cache/目录 * 默认不缓存 */public void setCache2File(boolean flag){impl.setCache2File(flag);}/** * 设置缓存路径,setCache2File(true)时有效 */public void setCachedDir(String dir){impl.setCachedDir(dir);}/**开启线程池*/public static void startThreadPoolIfNecessary(){if(sExecutorService == null || sExecutorService.isShutdown() || sExecutorService.isTerminated()){sExecutorService = Executors.newFixedThreadPool(3);//sExecutorService = Executors.newSingleThreadExecutor();}}/** * 异步下载图片,并缓存到memory中 * @param url * @param callbacksee ImageCallback interface */public void downloadImage(final String url, final ImageCallback callback){downloadImage(url, true, callback);}/** *  * @param url * @param cache2Memory 是否缓存至memory中 * @param callback */public void downloadImage(final String url, final boolean cache2Memory, final ImageCallback callback){if(sDownloadingSet.contains(url)){Log.i("AsyncImageLoader", "###该图片正在下载,不能重复下载!");return;}Bitmap bitmap = impl.getBitmapFromMemory(url);if(bitmap != null){if(callback != null){callback.onImageLoaded(bitmap, url);}}else{//从网络端下载图片sDownloadingSet.add(url);sExecutorService.submit(new Runnable(){@Overridepublic void run() {final Bitmap bitmap = impl.getBitmapFromUrl(url, cache2Memory);handler.post(new Runnable(){@Overridepublic void run(){if(callback != null)callback.onImageLoaded(bitmap, url);sDownloadingSet.remove(url);}});}});}}/** * 预加载下一张图片,缓存至memory中 * @param url  */public void preLoadNextImage(final String url){//将callback置为空,只将bitmap缓存到memory即可。downloadImage(url, null);}}


2.LoaderImpl.java

package com.imagecache;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.UnsupportedEncodingException;import java.lang.ref.SoftReference;import java.net.HttpURLConnection;import java.net.URL;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Map;import android.graphics.Bitmap;import android.graphics.BitmapFactory;/** *  * @author Administrator * @desc 异步加载图片管理器 * */public class LoaderImpl {//内存中的软应用缓存private Map<String, SoftReference<Bitmap>> imageCache;//是否缓存图片至本地文件private boolean cache2FileFlag = false;//缓存目录,默认是/data/data/package/cache/目录private String cachedDir;public LoaderImpl(Map<String, SoftReference<Bitmap>> imageCache){this.imageCache = imageCache;}/** * 是否缓存图片至外部文件 * @param flag  */public void setCache2File(boolean flag){cache2FileFlag = flag;}/** * 设置缓存图片到外部文件的路径 * @param cacheDir */public void setCachedDir(String cacheDir){this.cachedDir = cacheDir;}/** * 从网络端下载图片 * @param url 网络图片的URL地址 * @param cache2Memory 是否缓存(缓存在内存中) * @return bitmap 图片bitmap结构 *  */public Bitmap getBitmapFromUrl(String url, boolean cache2Memory){Bitmap bitmap = null;try{URL u = new URL(url);HttpURLConnection conn = (HttpURLConnection)u.openConnection();  InputStream is = conn.getInputStream();bitmap = BitmapFactory.decodeStream(is);if(cache2Memory){//1.缓存bitmap至内存软引用中imageCache.put(url, new SoftReference<Bitmap>(bitmap));if(cache2FileFlag){//2.缓存bitmap至/data/data/packageName/cache/文件夹中String fileName = getMD5Str(url);String filePath = this.cachedDir + "/" +fileName;FileOutputStream fos = new FileOutputStream(filePath);bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);}}is.close();conn.disconnect();return bitmap;}catch(IOException e){e.printStackTrace();return null;}}/** * 从内存缓存中获取bitmap * @param url * @return bitmap or null. */public Bitmap getBitmapFromMemory(String url){Bitmap bitmap = null;if(imageCache.containsKey(url)){synchronized(imageCache){SoftReference<Bitmap> bitmapRef = imageCache.get(url);if(bitmapRef != null){bitmap = bitmapRef.get();return bitmap;}}}//从外部缓存文件读取if(cache2FileFlag){bitmap = getBitmapFromFile(url);if(bitmap != null)imageCache.put(url, new SoftReference<Bitmap>(bitmap));}return bitmap;}/** * 从外部文件缓存中获取bitmap * @param url * @return */private Bitmap getBitmapFromFile(String url){Bitmap bitmap = null;String fileName = getMD5Str(url);if(fileName == null)return null;String filePath = cachedDir + "/" + fileName;try {FileInputStream fis = new FileInputStream(filePath);bitmap = BitmapFactory.decodeStream(fis);} catch (FileNotFoundException e) {e.printStackTrace();bitmap = null;}return bitmap;}/**       * MD5 加密       */       private static String getMD5Str(String str) {           MessageDigest messageDigest = null;           try {               messageDigest = MessageDigest.getInstance("MD5");               messageDigest.reset();               messageDigest.update(str.getBytes("UTF-8"));           } catch (NoSuchAlgorithmException e) {               System.out.println("NoSuchAlgorithmException caught!");               return null;        } catch (UnsupportedEncodingException e) {               e.printStackTrace();            return null;        }              byte[] byteArray = messageDigest.digest();           StringBuffer md5StrBuff = new StringBuffer();           for (int i = 0; i < byteArray.length; i++) {                           if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)                   md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));               else                   md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));           }              return md5StrBuff.toString();       }  /**       * MD5 加密      private static String getMD5Str(Object...objects){    StringBuilder stringBuilder=new StringBuilder();    for (Object object : objects) {stringBuilder.append(object.toString());}    return getMD5Str(stringBuilder.toString());    }*/ }

3.测试Activity

package com.imagecache;import android.app.Activity;import android.graphics.Bitmap;import android.os.Bundle;import android.widget.ImageView;public class MainActivity extends Activity {    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                final ImageView iv = (ImageView)findViewById(R.id.iv);        //网络图片地址        String imgUrl = "http://...";                //for test        AsyncImageLoader loader = new AsyncImageLoader(getApplicationContext());                //将图片缓存至外部文件中        loader.setCache2File(true);//false        //设置外部缓存文件夹        loader.setCachedDir(this.getCacheDir().getAbsolutePath());                //下载图片,第二个参数是否缓存至内存中        loader.downloadImage(imgUrl, true/*false*/, new AsyncImageLoader.ImageCallback() {@Overridepublic void onImageLoaded(Bitmap bitmap, String imageUrl) {if(bitmap != null){iv.setImageBitmap(bitmap);}else{//下载失败,设置默认图片}}});    }    }




更多相关文章

  1. Android之读取手机内存中的文件数据
  2. Android 通过Matrix来对图片进行缩放,旋转和平移
  3. android实现图片上传功能(springMvc)
  4. 举例说明android中Bitmap、ListView以及ImageView的综合使用---
  5. android 开发:保存图片到SD卡上
  6. [Android] 图片JNI(C++\Java)高斯模糊 多线程

随机推荐

  1. Android 控件之ProgressBar进度条
  2. Android软件测试的日志文件抓取简介
  3. Android——屏幕旋转时数据丢失问题解决
  4. Android Material Design调色板
  5. 从Eclipse迁移到Android(安卓)Stdio中
  6. Android客户端性能优化
  7. 一个不错的启动菜单显示屏动画效果
  8. Android 7.0 后拍照和相册选择
  9. Android 源代码编译前后的目录结构
  10. 使用android studio 来开发hello world a