android listview 滾動時非同步載入圖片的問題

l_serein發表於2012-05-08

 

LoadImage.java

 

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;  

        }  

 

    }  

 

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 )

 

 

Java程式碼 

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);  

                }  

            }  

        }  

 

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

 

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 "";  

        }  

    }    

 

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

 

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;  

            }  

        }  

 

 

 

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

相關文章