Android網絡請求圖片緩存本地無OOM支持安卓7.0

Android網絡請求圖片緩存本地無OOM支持安卓7.0

在開發中經常遇到異步網絡請求圖片,爲了節約流量經常需要把圖片存放在本地文件夾,下次請求直接讀取文件夾下面圖片。但有可能圖片太大造成內存溢出(OOM)。爲了解決這些問題專門寫了一個類來做這些事情。代碼註釋十分詳細。

1.網絡連接採用import java.net.URLConnection;更加快速,更加穩定
2.引入線程池管理
3.圖片存放本地,下次訪問快速
4.防止OOM【再多再大圖片無壓力】
5.使用簡單方便
6.可直接拖放到工程使用,很穩定

點擊這兒下載源代碼JAVA類。

1. 設置圖片方法舉例:

//高清4K
String url="http://attach.bbs.miui.com/forum/201502/03/150905vpzrbnzksnkbkyhr.jpg";
YnetImg yset=new YnetImg(getApplicationContext());
//路徑,imageView,清除錯誤時候默認加載的圖片
yset.set(url, imageView, R.drawable.a);

2. 清除本地緩存:

YnetImg img=new YnetImg(getApplicationContext());
img.clearCache();
    -

3.關鍵代碼

  1. 關鍵變量
// 硬引用緩存緩存Bitmap
private static LruCache<String, Bitmap> bitMapLruCache; 
// 硬引用緩存存請求隊列
private static LruCache<String, String> imageViewCache; 
// 記錄全部下載任務
downloads = new ArrayList<FileDownloadThread>();
/** 線程隊列同時最多運行10個 */
private static ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(10);
  1. 網絡請求,如果緩存有圖片直接設置給imageView,緩存沒有就本地找,本地沒有就網絡下載到本地然後設置給imageView,並且記錄給緩存
/**
     * @Title: set
     * @Description: TODO(網絡請求,如果緩存有圖片直接設置給imageView,緩存沒有就本地找,本地沒有就網絡下載到本地然後設置給imageView,並且記錄給緩存)
     * @param url
     *            下載路徑
     * @param imageView
     *            要設置的imageView
     * @param defaultImage
     *            出錯時顯示的defaultImage
     * @return void 返回類型
     */
    public void set(final String url, final ImageView imageView,
            final int defaultImage) {
        // 用戶傳遞空值直接拒絕繼續執行
        if (url == null || imageView == null || defaultImage == 0)
            return;
        if (bitMapLruCache.get(url) != null) {// 先在緩存中找圖片
            imageView.setImageBitmap(bitMapLruCache.get(url));// 顯示
            return;
        }
        // 判斷該imageView是否正在請求該網絡,若是則不請求
        if (imageViewCache.get(url + imageView.toString()) != null
                && (url + imageView.toString()).equals(imageViewCache.get(url
                        + imageView.toString()))) {// 先在緩存中找圖片
            return;
        }
        imageViewCache.put(url + imageView.toString(),
                url + imageView.toString());
        // 給保存文件命名
        String fileName = MD5Util.MD5(url) + getLastName(url);
        // 開始請求網絡
        YDownload download = new YDownload(url, path, fileName,
                new YDownloadImgListener() {
                    @Override
                    public void response(boolean issuccess, String url,
                            String path, String fileName) {
                        // 請求回調結果
                        imageViewCache.remove(url + imageView.toString());// 在請求隊列中把刪除
                        // 請求是否成功
                        if (issuccess) {
                            // 這樣要內存溢出
                            // Bitmap bitmap =
                            // BitmapFactory.decodeFile(path+"/"+ fileName);
                            // 這樣可以防止內存溢出
                            Bitmap bitmap = BitmapFactory.decodeByteArray(
                                    BitmapMemory.decodeBitmap(path + "/"
                                            + fileName),
                                    0,
                                    BitmapMemory.decodeBitmap(path + "/"
                                            + fileName).length);
                            if (bitmap == null) {
                                Log.e("錯誤", "讀取的文件不能轉換成bitmap");
                                Bitmap bmp = BitmapFactory.decodeResource(
                                        context.getResources(), defaultImage);
                                imageView.setImageBitmap(bmp);// 顯示默認圖片
                                return;
                            }
                            bitMapLruCache.put(url, bitmap);// 把bitmap添加保存起來
                            imageView.setImageBitmap(bitmap);// 顯示
                        } else {
                            // 把資源文件轉換成bitmap
                            Bitmap bmp = BitmapFactory.decodeResource(
                                    context.getResources(), defaultImage);
                            imageView.setImageBitmap(bmp);// 顯示默認圖片
                        }
                    }
                });
        download.setDiskCache(true);// 是否開啓緩存
        download.setTimeOut(8000);// 設置延遲
        download.start();// 開始,將開啓一個線程丟入線程隊列
    }
  1. 初始化緩存
    /**
     * 初始化緩存
     */
    private void setImageCache() {
        if (bitMapLruCache == null) {
            int memClass = (((ActivityManager) context
                    .getSystemService(Context.ACTIVITY_SERVICE)))
                    .getMemoryClass();
            int cacheSize = 1024 * 1024 * memClass / 10; // 硬引用緩存容量,爲系統可用內存的1/10
            bitMapLruCache = new LruCache<String, Bitmap>(cacheSize) {
                @SuppressLint("NewApi")
                @Override
                protected int sizeOf(String key, Bitmap bitmap) {
                    if (bitmap != null) {// 返回bitmap大小
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {// API
                                                                                    // 19
                            return bitmap.getAllocationByteCount();
                        }
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {// API
                                                                                            // 12
                            return bitmap.getByteCount();
                        }
                        return bitmap.getRowBytes() * bitmap.getHeight(); // earlierversion
                    } else
                        return 0;
                }
            };
        }
        if (imageViewCache == null) {
            int memClass = (((ActivityManager) context
                    .getSystemService(Context.ACTIVITY_SERVICE)))
                    .getMemoryClass();
            int cacheSize = 1024 * 1024 * memClass / 10; // 硬引用緩存容量,爲系統可用內存的1/10
            imageViewCache = new LruCache<String, String>(cacheSize);
        }
    }

希望大家多多提出意見一起努力進步。
點擊這兒下載源代碼JAVA類。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章