升级 24%
- 精华
- 0
- 帖子
- 198
- e币
- 997 元
|
以前发过一篇有关加载图片的文章,是处理应用中常常遇到的加载列表缩略图与大图的文章,当时是因为赶项目,时间仓促,并没有过多的考虑,闲暇时间,反思了一下,觉得以前所用的方法过于笨拙且消耗手机资源加大,思量再三,又重新做了一个 此次引用了线程池ExecutorService与改用了Handler的post方法
采用线程池的目的: 1、大幅减少开启线程的数量,重复利用有限的线程 2、减少手机的资源损耗
采用Handler的Post方法的目的: 1、是为了更加规范的调用API 2、是图片的呈现更加可靠
<ignore_js_op>
不多说了!
------------------------------------------------------------------------------------------------------------------------------- java代码:
图片加载管理类AsynDownloadManager,需要从外部传入UI线程的Handler
public class AsynDownloadManager { private static String ThumbFolder = "Temp/Thumb";//缩略图文件夹 private static String ImageFolder="Temp/Image";//大图文件夹 private static Handler handler;//UI handler private static ExecutorService pool;//线程池 private static Map<String, SoftReference<Bitmap>> cacheImage;//软引用 private int ThreadCount=5;//默认线程池可用线程数 /** * 创建目录 */ static { if (isSDCardAvailable()) { File file = new File(Environment.getExternalStorageDirectory(),ThumbFolder); if (!file.exists()) { file.mkdirs(); } File file1 = new File(Environment.getExternalStorageDirectory(),ImageFolder); if (!file1.exists()) { file1.mkdirs(); } } } public AsynDownloadManager() { cacheImage = new HashMap<String, SoftReference<Bitmap>>(); pool = Executors.newFixedThreadPool(ThreadCount); } static AsynDownloadManager manager=null; //**********************************************************************************供外部调用的主方法 /** * 获取加载器 * @return AsynDownloadManager */ public static AsynDownloadManager getInterface(){ if(manager==null){ manager=new AsynDownloadManager(); } return manager; } /** * 加载图片(缩略图) * @param url * @param imageView */ public static void loadThembBitmap(final String url, final ImageView imageView) { pool.submit(new Runnable() { public void run() { //首先从SoftReference中获取 Bitmap bitmapTemp=getFromSoftReference(url); if(bitmapTemp==null){ //从SDcard中获取 bitmapTemp=getFromSDcard(url, ThumbFolder,false); if(bitmapTemp==null){ //从URL获取 bitmapTemp=getFromURL(url, ThumbFolder,false); } } final Bitmap bitmap=bitmapTemp; handler.post(new Runnable() {//发送到Handler队列,依次显示 public void run() { imageView.setImageBitmap(bitmap); } }); } }); } /** * 加载图片(大图) * @param url * @param imageView * @param isZip 是否压缩 */ public static void loadBitmap(final String url, final ImageView imageView,final boolean isZip){ pool.submit(new Runnable() { public void run() { //因为单图较大,不用SoftReference Bitmap bitmapTemp=null; //从SDcard中获取 bitmapTemp=getFromSDcard(url, ImageFolder,isZip); if(bitmapTemp==null){ //从URL获取 bitmapTemp=getFromURL(url, ImageFolder,isZip); } final Bitmap bitmap=bitmapTemp; handler.post(new Runnable() {//发送到Handler队列,依次显示 public void run() { imageView.setImageBitmap(bitmap); } }); } }); } //********************************************************************************** /** * 从缓存中获取 * @param url * @param bitmap * @return Bitmap */ public static Bitmap getFromSoftReference(String url){ if(!cacheImage.containsKey(url)){ return null; }else{ return cacheImage.get(url).get(); } } /** * 从SDcard获取(下载并返回) * @param imageUrl * @param folderPath * @return Bitmap */ public static Bitmap getFromURL(String imageUrl, String folderPath,boolean isZip){ URL mUrl; InputStream is = null; Bitmap bitmap = null; try { mUrl = new URL(imageUrl); is = (InputStream) mUrl.getContent(); if(isSDCardAvailable()){ String fileName = imageUrl.substring(imageUrl.lastIndexOf('/')+1); File basePathFile = new File(Environment.getExternalStorageDirectory(), folderPath); File file = new File(basePathFile, fileName+".tmp"); if(!file.exists()){ file.createNewFile(); } FileOutputStream outputStream = new FileOutputStream(file); byte[] b = new byte[512]; int offset; while((offset=is.read(b))!=-1){ outputStream.write(b, 0, offset); } outputStream.flush(); outputStream.close(); is.close(); basePathFile = new File(basePathFile, fileName); if(basePathFile.exists()){ basePathFile.delete(); } if(file.renameTo(basePathFile)){ is = new FileInputStream(basePathFile); } // 读取图片 bitmap=getBitmap(basePathFile.getAbsolutePath(), isZip); if(isZip==false){ //缩略图加入到软引用 SoftReference<Bitmap> softReference=new SoftReference<Bitmap>(bitmap); cacheImage.put(imageUrl, softReference); } } } catch (Exception e) { e.printStackTrace(); return null; }
return bitmap; } /** * 从SDcard获取 * @param url * @param folderPath * @return Bitmap */ public static Bitmap getFromSDcard(String url,String folderPath,boolean isZip){ Bitmap bitmap = null; String fileName = url.substring(url.lastIndexOf('/')+1); File basePathFile = new File(Environment.getExternalStorageDirectory(), folderPath); basePathFile = new File(basePathFile, fileName); if(basePathFile.exists()){ bitmap=getBitmap(basePathFile.getAbsolutePath(), isZip); } return bitmap; } /** * 检查SDCard是否可用 * * @return */ public static final boolean isSDCardAvailable() { return Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED); }
//--------------------------------------------------------------------------------- /** * 读取SDcard中的图片资源(解决内存溢出问题) * @param pathName 文件路径名 * @param isZip 是否降低采样率 * @return Bitmap */ public static Bitmap getBitmap(String pathName,boolean isZip){ Bitmap bitmap=null; if(isZip==true){ BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2;//图片宽高都为原来的二分之一,即图片为原来的四分之一 bitmap=BitmapFactory.decodeFile(pathName, options); }else{ bitmap=BitmapFactory.decodeFile(pathName); } return bitmap; }
//---------------------------------------------------------------便于外部修改参数 public static String getThumbFolder() { return ThumbFolder; }
public static void setThumbFolder(String thumbFolder) { ThumbFolder = thumbFolder; }
public static String getImageFolder() { return ImageFolder; }
public static void setImageFolder(String imageFolder) { ImageFolder = imageFolder; }
public int getThreadCount() { return ThreadCount; }
public void setThreadCount(int threadCount) { ThreadCount = threadCount; }
public Handler getHandler() { return handler; }
public void setHandler(Handler handler) { this.handler = handler; }
}
------------------------------------------------------------------------------------------------------------------------------ 调用示例:
一、对于缩略图: 1、在Activity中实例化AsynDownloadManager: Handler handler=new Handler();
2、对于ListView或GridView中的缩略图,一般可在自定义Adapter的的构造中: AsynDownloadManager manager=AsynDownloadManager.getInterface(); manager.setHandler(handler);
getView()方法中作如下调用: manager.loadThembBitmap(urlList.get(position), imageView);
3、OK
二、对于大图:(压缩)
前两步同上
3、 直接调用 AsynDownloadManager.getInterface().loadBitmap(url, ImageView, true); 当然最后那个参数也可以用false,即不压缩的模式
---------------------------------------------------------------------------------------------------------------------------------
OK! |
|