• 异步图片下载引擎(升级版——ExecutorService+handler)


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

      [复制链接]
       

    13

    主题

    5

    好友

    844

    积分

    No.4 中级开发者

    Rank: 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>device-2013-04-07-143747.png 

    不多说了!

    -------------------------------------------------------------------------------------------------------------------------------
    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!
  • 相关阅读:
    工具包分享-常用工具。by-某某
    渗透常用dos命令,http协议及数据提交方式。 hack 某某
    Hello This Cruel World!
    FFT的一个小技巧
    未完成的模板
    进制转换详细讲解
    CodeForces练习计划
    [SDOI2013]随机数生成器-题解
    动态dp模板
    noip2018游记
  • 原文地址:https://www.cnblogs.com/wanqieddy/p/3181393.html
Copyright © 2020-2023  润新知