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上SD卡图片的标准缓存方法
  5. Android 关于 如何使用外界导入的数据库文件
  6. Android实现图片预览浏览功能
  7. android 将图片转换成二进制,再讲二进制转换成图片 可用于编码加
  8. android 重命名文件
  9. Android WebView加载本地Html文件

随机推荐

  1. Android当前时间的获取
  2. android AudioManager
  3. Android(安卓)双击退出应用
  4. Android(安卓)Studio 无法预览xml布局视
  5. 解决Could not find method android() fo
  6. Delphi XE5 Android(安卓)调用手机震动
  7. Android中控制虚拟键盘
  8. Android常见面试题总结 1.1
  9. Android(安卓)开发常用代码片段
  10. 菜鸟的安卓实习之路----editText 只允许