[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. ScheduledThreadExecutor定时任务线程池

    ScheduledThreadPoolExecutor 继承自ThreadPoolExecutor实现了ScheduledExecutorService接口.主要完成定时或者周期的执行线程任务. 代码 ...

  2. oracle数据库_实例_用户_表空间之间的关系

    基础概念:Oracle数据库.实例.用户.表空间.表之间的关系 数据库:Oracle数据库是数据的物理存储.这就包括(数据文件ORA或者DBF.控制文件.联机日志.参数文件).其实Oracle数据库的 ...

  3. RandomForest随机森林总结

    1.随机森林原理介绍 随机森林,指的是利用多棵树对样本进行训练并预测的一种分类器.该分类器最早由Leo Breiman和Adele Cutler提出,并被注册成了商标.简单来说,随机森林就是由多棵CA ...

  4. Java编程的逻辑 (2) - 赋值

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  5. java安装1.8的经验和Error: Registry key 'Software\JavaSoft\Java Runtime Environment'\CurrentVers问题处理

            java安装1.8后的问题:之前安装了jdk1.7和jdk1.6,之后又安装jdk1.8,然后执行java -version,输出的是1.8的,后来在注册表把jdk1.8改为1.7,然 ...

  6. Linux性能优化之CPU优化(一)

    前言 何为性能优化?个人认为,性能优化是为了提高应用程序或系统能力为目的.那么如何才能实现对应用程序的性能调优呢?这里很设计到很多的内容,包括Linux内核.CPU架构以及Linux内核对资源的分配以 ...

  7. Card Game Cheater HDU1528

    二分图最大匹配问题 扑克题还是用map比较方便 #include<bits/stdc++.h> using namespace std; #define MAXI 52 ]; ]; int ...

  8. linux密码暴力破解机

    linux 密码保存在 /etc/shadow shadow 文件的保存格式 python:$$mWSyC6Pv$hpMreQT77R9ML/Xx1QnRAow1tUTDjIowaTssV7bZw9S ...

  9. pymysql模块 执行sql封装

    封装pymysql模块执行sql class HandCost(object): """ 处理数据库中的数据 """ def __init_ ...

  10. CMU-15445 LAB1:Extendible Hash Table, LRU, BUFFER POOL MANAGER

    概述 最近又开了一个新坑,CMU的15445,这是一门介绍数据库的课程.我follow的是2018年的课程,因为2018年官方停止了对外开放实验源码,所以我用的2017年的实验,但是问题不大,内容基本 ...