[Android分享] 异步图片下载引擎(升级版——ExecutorService+handler)

 [复制链接]

   

13

主题

5

好友

844

积分

No.4 中级开发者

升级  24%

精华
0
帖子
198
e币
997 元
电梯直达

楼主

 
 发表于 2013-4-7 14:39:10 |只看该作者 |正序浏览

以前发过一篇有关加载图片的文章,是处理应用中常常遇到的加载列表缩略图与大图的文章,当时是因为赶项目,时间仓促,并没有过多的考虑,闲暇时间,反思了一下,觉得以前所用的方法过于笨拙且消耗手机资源加大,思量再三,又重新做了一个
此次引用了线程池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!

异步图片下载引擎(升级版——ExecutorService+handler)的更多相关文章

  1. iOS学习笔记之异步图片下载

    写在前面 在iOS开发中,无论是在UITableView还是在UICollectionView中,通过网络获取图片设置到cell上是较为常见的需求.尽管有很多现存的第三方库可以将下载和缓存功能都封装好 ...

  2. iOS异步图片加载优化与常用开源库分析

    网络图片显示大体步骤: 1.下载图片: 2.图片处理(裁剪,边框等): 3.写入磁盘: 4.从磁盘读取数据到内核缓冲区: 5.从内核缓冲区复制到用户空间(内存级别拷贝): 6.解压缩为位图(耗cpu较 ...

  3. iOS利用SDWebImage图片下载缓存

    一.我们先来了解一下SDWebImage的使用: 1.导入框架,引入头文件: #import "UIImageView+WebCache.h" 也可以直接使用CocoaPods来引 ...

  4. RuPengGame游戏引擎 精灵 createSprite 创建 setSpritePosition 设置位置 playSpriteAnimate 播放动画 setSpriteFlipX设置翻转 精灵图片下载地址

    package com.swift; import java.awt.Point; import com.rupeng.game.GameCore;//导入游戏引擎包 public class Gam ...

  5. picasso-强大的Android图片下载缓存库

    编辑推荐:稀土掘金,这是一个针对技术开发者的一个应用,你可以在掘金上获取最新最优质的技术干货,不仅仅是Android知识.前端.后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过! pica ...

  6. picasso_强大的Android图片下载缓存库

    tag: android pic skill date: 2016/07/09 title: picasso-强大的Android图片下载缓存库 [本文转载自:泡在网上的日子 参考:http://bl ...

  7. listView异步处理图片下载缓存

    package cn.wangmeng.test; import java.io.File;import java.io.FileOutputStream;import java.io.IOExcep ...

  8. Android 框架修炼-自己开发高效异步图片加载框架

    一.概述 目前为止,第三方的图片加载框架挺多的,比如UIL , Volley Imageloader等等.但是最好能知道实现原理,所以下面就来看看设计并开发一个加载网络.本地的图片框架. 总所周知,图 ...

  9. Android高效异步图片加载框架

    概述 Android高效异步图片加载框架:一个高效的异步加载显示的图片加载框架,同时具备图片压缩,缓存机制等特性. 详细 代码下载:http://www.demodashi.com/demo/1214 ...

随机推荐

  1. Android 隐藏虚拟按键,并且全屏

    /** * 隐藏虚拟按键,并且全屏 */protected void hideBottomUIMenu() { //隐藏虚拟按键,并且全屏 if (Build.VERSION.SDK_INT > ...

  2. P2429 制杖题

    P2429 制杖题这个题用线性筛会WA一个点,因为这个题是给定的质数集,最大的质数会比当前的倍数大,就会出现上面的情况.怎办?判重用set啊!set+线性筛就过掉了.16ms #include< ...

  3. 002.NTP服务端搭建

    一 安装及准备 1.1 安装NTP [root@server ~]# yum -y install ntp #也可下载之后rpm安装,或者源码安装 1.2 NTP服务地址 http://www.ntp ...

  4. 使用React Hooks新特性useReducer、useContext替代传统Redux高阶组件案例

    当我们使用redux进行数据管理的时候,一般都是在根组件通过Provider的方式引入store,然后在每个子组件中,通过connect的方式使用高阶组件进行连接,这样造成的一个问题是,大量的高阶组件 ...

  5. ApiPost自动化测试基础之:流程测试

    我们在<ApiPost自动化测试基础之:接口参数依赖的情景处理>和<ApiPost自动化测试基础之:如何使用测试校验(测试用例)?>分别讲解了ApiPost自动化测试的基础知识 ...

  6. 减少Building 'Xxx' Gradle project info等待时间

    转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6640279.html 从Github上看到好的Demo想要Download下来学习.导入到Android ...

  7. Swift map filter reduce 使用指南

    转载:https://useyourloaf.com/blog/swift-guide-to-map-filter-reduce/ Using map, filter or reduce to ope ...

  8. php版本CKFinder3.4.4自定义上传文件位置

    1.修改文件上传路径: 编辑ckfinder目录下config.php,70行设置为:    'baseUrl'      => '/uploads/'.date('Ymd').'/'; 这样上 ...

  9. Codeforces.643E.Bear and Destroying Subtrees(DP 期望)

    题目链接 \(Description\) 有一棵树.Limak可以攻击树上的某棵子树,然后这棵子树上的每条边有\(\frac{1}{2}\)的概率消失.定义 若攻击以\(x\)为根的子树,高度\(ht ...

  10. C# 实现IDisposable的模式

    来自MSDN官方文档:http://msdn.microsoft.com/en-us/library/system.configuration.provider.providercollection. ...