LoadImage.java

package com.gowin.cach;import java.util.Collection;import java.util.HashMap;import java.util.Map;import java.util.concurrent.Callable;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import android.graphics.Bitmap;import android.os.Handler;import android.os.Message;import android.widget.ImageView;public class LoadImage {    private ExecutorService executorService; // 固定五个线程来    private ImageMemoryCache memoryCache;// 内存缓存    private ImageFileCache fileCache;// 文件缓存    private Map<String, ImageView> taskMap;// 存放任务    public LoadImage() {        executorService = Executors.newFixedThreadPool(10);        memoryCache = new ImageMemoryCache();        fileCache = new ImageFileCache();        taskMap = new HashMap<String, ImageView>();    }    public void addTask(String url, ImageView img) {        Bitmap bitmap=memoryCache.getBitmapFromCache(url);        if(bitmap!=null)        {            img.setImageBitmap(bitmap);        }else        {        synchronized (taskMap) {        taskMap.put(Integer.toString(img.hashCode()), img);        }        }    }    public void doTask() {        synchronized (taskMap) {            Collection<ImageView> con = taskMap.values();            for (ImageView i : con) {                if (i != null) {                    if (i.getTag() != null) {                        loadImage((String) i.getTag(), i);                    }                }            }            taskMap.clear();        }    }    private void loadImage(String url, ImageView img) {        /*** 加入新的任务 ***/        executorService.submit(new TaskWithResult(new TaskHandler(url, img),                url));    }    /*** 获得一个图片,从三个地方获取,首先是内存缓存,然后是文件缓存,最后从网络获取 ***/    private Bitmap getBitmap(String url) {        // 从内存缓存中获取图片        Bitmap result;        result = memoryCache.getBitmapFromCache(url);        if (result == null) {            // 文件缓存中获取            result = fileCache.getImage(url);            if (result == null) {                // 从网络获取                result = ImageGetForHttp.downloadBitmap(url);                if (result != null) {                    memoryCache.addBitmapToCache(url, result);                    fileCache.saveBmpToSd(result, url);                                    }            } else {                // 添加到内存缓存                memoryCache.addBitmapToCache(url, result);            }        }        return result;    }    /*** 完成消息 ***/    private class TaskHandler extends Handler {        String url;        ImageView img;        public TaskHandler(String url, ImageView img) {            this.url = url;            this.img = img;        }        @Override        public void handleMessage(Message msg) {            /*** 查看imageview需要显示的图片是否被改变 ***/            if (img.getTag().equals(url)) {                if (msg.obj != null) {                    Bitmap bitmap = (Bitmap) msg.obj;                    img.setImageBitmap(bitmap);                }            }        }    }    /*** 子线程任务 ***/    private class TaskWithResult implements Callable<String> {        private String url;        private Handler handler;        public TaskWithResult(Handler handler, String url) {            this.url = url;            this.handler = handler;        }        @Override        public String call() throws Exception {            Message msg = new Message();            msg.obj = getBitmap(url);            if (msg.obj != null) {                handler.sendMessage(msg);            }            return url;        }    }}

ImageMemoryCache.java (http://www.my400800.cn )

package com.gowin.cach;import java.lang.ref.SoftReference;import java.util.HashMap;import java.util.LinkedHashMap;import java.util.concurrent.ConcurrentHashMap;import android.graphics.Bitmap;/**** *内存中的缓存  ****/public class ImageMemoryCache {      private static final int HARD_CACHE_CAPACITY = 30;      private HashMap<String, Bitmap> mHardBitmapCache ;      private final static ConcurrentHashMap<String, SoftReference<Bitmap>> mSoftBitmapCache =            new ConcurrentHashMap<String, SoftReference<Bitmap>>(HARD_CACHE_CAPACITY / 2);                    public ImageMemoryCache()            {          mHardBitmapCache =                new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY / 2, 0.75f, true) {                /**                     *                      */                    private static final long serialVersionUID = 1L;                @Override                protected boolean removeEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) {                    if (size() > HARD_CACHE_CAPACITY) {                        // Entries push-out of hard reference cache are transferred to soft reference cache                        mSoftBitmapCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue()));                        return true;                    } else                        return false;                }            };      }            /**      * 从缓存中获取图片      */      public Bitmap getBitmapFromCache(String url) {      // 先从mHardBitmapCache缓存中获取      synchronized (mHardBitmapCache) {      final Bitmap bitmap =mHardBitmapCache.get(url);      if (bitmap != null) {      //如果找到的话,把元素移到linkedhashmap的最前面,从而保证在LRU算法中是最后被删除      mHardBitmapCache.remove(url);      mHardBitmapCache.put(url,bitmap);      return bitmap;      }      }      //如果mHardBitmapCache中找不到,到mSoftBitmapCache中找      SoftReference<Bitmap>bitmapReference = mSoftBitmapCache.get(url);      if (bitmapReference != null) {      final Bitmap bitmap =bitmapReference.get();      if (bitmap != null) {          //将图片移回硬缓存          mHardBitmapCache.put(url, bitmap);          mSoftBitmapCache.remove(url);      return bitmap;      } else {      mSoftBitmapCache.remove(url);      }      }      return null;      }       /***添加图片到缓存***/      public void addBitmapToCache(String url, Bitmap bitmap) {            if (bitmap != null) {                synchronized (mHardBitmapCache) {                    mHardBitmapCache.put(url, bitmap);                }            }        }}

ImageFileCache.java

package com.gowin.cach;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.util.Arrays;import java.util.Comparator;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Environment;import android.os.StatFs;import android.util.Log;public class ImageFileCache {    private static final String CACHDIR = "data/gowin/imgCach";    private static final String WHOLESALE_CONV = ".cach";    /**过期时间3天**/    private static final long mTimeDiff = 3 * 24 * 60 * 60 * 1000;    public ImageFileCache()    {        //清理文件缓存        removeCache(getDirectory());    }        public Bitmap getImage(final String url) {            final String path = getDirectory() + "/" + convertUrlToFileName(url);        File file = new File(path);        if (file.exists()) {            Bitmap bmp=BitmapFactory.decodeFile(path);            if(bmp==null)            {                file.delete();            }else            {                updateFileTime(path);                return bmp;            }        }        return null;    }        /***缓存空间大小****/    private static final int FREE_SD_SPACE_NEEDED_TO_CACHE=10;    public void saveBmpToSd(Bitmap bm, String url) {        if (bm == null) {                //需要保存的是一个空值            return;        }        //判断sdcard上的空间        if (FREE_SD_SPACE_NEEDED_TO_CACHE >freeSpaceOnSd()) {        //SD空间不足        return;        }        String filename =convertUrlToFileName(url);        String dir = getDirectory();        File file = new File(dir +"/" + filename);        try {        file.createNewFile();        OutputStream outStream = new FileOutputStream(file);        bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);        outStream.flush();        outStream.close();            } catch (FileNotFoundException e) {        Log.w("ImageFileCache","FileNotFoundException");        } catch (IOException e) {        Log.w("ImageFileCache","IOException");        }        }             private static final int CACHE_SIZE=10;        // 清理缓存    /**     * 计算存储目录下的文件大小,     * 当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定     * 那么删除40%最近没有被使用的文件     *      * @param dirPath     * @param filename     */    private boolean removeCache(String dirPath) {        File dir = new File(dirPath);        File[] files = dir.listFiles();        if (files == null) {            return true;        }        if (!android.os.Environment.getExternalStorageState().equals(                android.os.Environment.MEDIA_MOUNTED)) {            return false;        }        int dirSize = 0;        for (int i = 0; i < files.length; i++) {            if (files[i].getName().contains(WHOLESALE_CONV)) {                dirSize += files[i].length();            }        }        if (dirSize > CACHE_SIZE * MB                || FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) {            int removeFactor = (int) ((0.4 * files.length) + 1);            Arrays.sort(files, new FileLastModifSort());            Log.i("ImageFileCache", "清理缓存文件");            for (int i = 0; i < removeFactor; i++) {                if (files[i].getName().contains(WHOLESALE_CONV)) {                    files[i].delete();                }            }        }        if (freeSpaceOnSd() <= CACHE_SIZE) {            return false;        }        return true;    }    /**     * TODO 根据文件的最后修改时间进行排序 *     */    private class FileLastModifSort implements Comparator<File> {        public int compare(File arg0, File arg1) {            if (arg0.lastModified() > arg1.lastModified()) {                return 1;            } else if (arg0.lastModified() == arg1.lastModified()) {                return 0;            } else {                return -1;            }        }    }        /**     * 删除过期文件     *      * @param dirPath     * @param filename     */    public void removeExpiredCache(String dirPath, String filename) {        File file = new File(dirPath, filename);        if (System.currentTimeMillis() - file.lastModified() > mTimeDiff) {            Log.i("ImageFileCache", "Clear some expiredcache files ");            file.delete();        }    }        /**     * 修改文件的最后修改时间     * 这里需要考虑,是否将使用的图片日期改为当前日期     * @param path     */    public void updateFileTime(String path) {        File file = new File(path);        long newModifiedTime = System.currentTimeMillis();        file.setLastModified(newModifiedTime);    }    /**    * 计算sdcard上的剩余空间    * @return    */    private int MB=1024*1024;    private int freeSpaceOnSd() {    StatFs stat = new StatFs(Environment.getExternalStorageDirectory() .getPath());    double sdFreeMB = ((double)stat.getAvailableBlocks() * (double) stat.getBlockSize()) / MB;    return (int) sdFreeMB;    }         /**将url转成文件名**/    private String convertUrlToFileName(String url) {        String[] strs = url.split("/");        return strs[strs.length - 1] + WHOLESALE_CONV;    }    /**获得缓存目录**/    private String getDirectory() {        String dir = getSDPath() + "/" + CACHDIR;        String substr = dir.substring(0, 4);        if (substr.equals("/mnt")) {            dir = dir.replace("/mnt", "");        }        return dir;    }    /**** 取SD卡路径不带/ ****/    public String getSDPath() {        File sdDir = null;        boolean sdCardExist = Environment.getExternalStorageState().equals(                android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在        if (sdCardExist) {            sdDir = Environment.getExternalStorageDirectory();// 获取跟目录        }        if(sdDir!=null)        {        return sdDir.toString();        }else        {            return "";        }    }  }

ImageGetForHttp.java

package com.gowin.cach;import java.io.FilterInputStream;import java.io.IOException;import java.io.InputStream;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.HttpStatus;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.http.AndroidHttpClient;import android.util.Log;public class ImageGetForHttp {    private static final String LOG_TAG="ImageGetForHttp";     public static Bitmap downloadBitmap(String url) {            //final int IO_BUFFER_SIZE = 4 * 1024;            // AndroidHttpClient is not allowed to be used from the main thread            final HttpClient client = AndroidHttpClient.newInstance("Android");            final HttpGet getRequest = new HttpGet(url);            try {                HttpResponse response = client.execute(getRequest);                final int statusCode = response.getStatusLine().getStatusCode();                if (statusCode != HttpStatus.SC_OK) {                    Log.w("ImageDownloader", "Error " + statusCode +                            " while retrieving bitmap from " + url);                    return null;                }                final HttpEntity entity = response.getEntity();                if (entity != null) {                    InputStream inputStream = null;                    try {                        inputStream = entity.getContent();                        // return BitmapFactory.decodeStream(inputStream);                        // Bug on slow connections, fixed in future release.                        FilterInputStream fit= new FlushedInputStream(inputStream);                        return BitmapFactory.decodeStream(fit);                    } finally {                        if (inputStream != null) {                            inputStream.close();                        }                        entity.consumeContent();                    }                }            } catch (IOException e) {                getRequest.abort();                Log.w(LOG_TAG, "I/O error while retrieving bitmap from " + url, e);            } catch (IllegalStateException e) {                getRequest.abort();                Log.w(LOG_TAG, "Incorrect URL: " + url);            } catch (Exception e) {                getRequest.abort();                Log.w(LOG_TAG, "Error while retrieving bitmap from " + url, e);            } finally {                if ((client instanceof AndroidHttpClient)) {                    ((AndroidHttpClient) client).close();                }            }            return null;        }          /*         * An InputStream that skips the exact number of bytes provided, unless it reaches EOF.         */        static class FlushedInputStream extends FilterInputStream {            public FlushedInputStream(InputStream inputStream) {                super(inputStream);            }            @Override            public long skip(long n) throws IOException {                long totalBytesSkipped = 0L;                while (totalBytesSkipped < n) {                    long bytesSkipped = in.skip(n - totalBytesSkipped);                    if (bytesSkipped == 0L) {                        int b = read();                        if (b < 0) {                            break;  // we reached EOF                        } else {                            bytesSkipped = 1; // we read one byte                        }                    }                    totalBytesSkipped += bytesSkipped;                }                return totalBytesSkipped;            }        }}

使用时,要救imageview的tag是需要下载的url

在getview时先addtask

当滚动停止的时候调用doTask

更多相关文章

  1. Android读取XML文件(SAX)
  2. Android(安卓)获取屏幕分辨率
  3. Android(安卓)定时获取系统内存信息
  4. Android(安卓)仿苹果底部弹出Dialog
  5. Android(安卓)文件下载与解压缩
  6. java android 获取手机操作系统相关信息
  7. Android(安卓)intent跳转工具类
  8. NPM 和webpack 的基础使用
  9. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程

随机推荐

  1. Android中RelativeLayout中各个属性的用
  2. android的PowerManager和PowerManager.Wa
  3. 初识android
  4. Android(Java):Android(安卓)事件分发机
  5. Android应用程序启动过程源代码分析
  6. 【Tech-Android-Other】android中的Parce
  7. android Content Provider 详解
  8. [转]Android(安卓)实现TextView中文字链
  9. android 实现静默安装、卸载(图)
  10. 个人对android中项目命名规则的整理