1. 程式人生 > >某宅的Android學習筆記(二)——圖片三級快取

某宅的Android學習筆記(二)——圖片三級快取

圖片三級快取的重要性

 很多時候我們都需要從網路上下載圖片,如果在圖片很多的情況下,每次啟動app都要從網上下載,就會造成流量的浪費,影響使用者的體驗。因此,要利用快取來避免圖片的重複載入。

圖片快取方式

 所謂三級快取,即:

  • 網路快取
  • 記憶體快取
  • 本地快取

 在載入圖片時,優先訪問記憶體快取,如果沒有結果,再去訪問本地檔案;如果都沒有結果,才去從網路下載圖片。並且在圖片下載之後,要將圖片快取到記憶體和本地。
 其實嚴格來說網路並不能算是快取,不過這裡姑且這麼叫吧。

依次實現三級快取

1.本地快取

 private static final String LOCAL_CACHE_PATH =
 Environment.getExternalStorageDirectory().getAbsolutePath() + "/ImgCache";//本地檔案儲存路徑

/**
 * 從本地獲取圖片
 */
private Bitmap getBitmapFromLocalCache(String url) {
    Bitmap bitmap = null;
    String fileName = url;
    File file = new File(LOCAL_CACHE_PATH, fileName);//將url作為檔名
    try {
        bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    return bitmap;
}

/**
 * 將圖片儲存到本地
 */
private void addBitmapToLocalCache(String url, Bitmap bitmap) {
    String fileName = url;
    File file = new File(LOCAL_CACHE_PATH, fileName);//將url作為檔名
    File parentFile = file.getParentFile();
    if (!parentFile.exists()) {//判斷父檔案是否存在
        parentFile.mkdirs();
    }
    try {
        //儲存圖片
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, new FileOutputStream(file));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

2.記憶體快取

 這裡使用LruCache()——近期最少使用演算法來控制快取的大小,以避免出現OOM。

private static LruCache<String, Bitmap> memoryCaches;

//私有化構造方法以保證物件全域性唯一性
private ImageLoader(ListView listView) {
    this.listView = listView;
    tasks = new HashSet<>();
    //設定快取區的大小
    if (memoryCaches == null) {
        int maxMemory = (int) Runtime.getRuntime().maxMemory();
        int cacheSize = maxMemory / 4;
        memoryCaches = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getByteCount();
            }
        };
    }
}

//單例化ImageLoader
public static ImageLoader getImageLoader(ListView mListView) {
    imageLoader = new ImageLoader(mListView);
    return imageLoader;
}

 在設定好記憶體快取大小之後,同樣需要新增相應的方法。

/**
 * 從記憶體快取獲取bitmap
 */
private Bitmap getBitmapFromLruCache(String url) {
    return memoryCaches.get(url);
}

/**
 * 向記憶體快取中新增bitmap
 */
private void addBitmapToLruCache(String url, Bitmap bitmap) {
    if (getBitmapFromLruCache(url) == null) {
        memoryCaches.put(url, bitmap);
    }
}

3.網路快取

 從網路下載圖片,通過AsyncTask來進行非同步載入。

/**
 * 利用AsyncTask來完成非同步載入圖片
 */
private class imgAsyncTask extends AsyncTask<String, Void, Bitmap> {

    private String url;

    public imgAsyncTask(String url) {
        this.url = url;
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        String url = params[0];
        Bitmap bitmap = getBitmapFromUrl(url);
        if (bitmap != null) {
            addBitmapToLruCache(url, bitmap);//將bitmap新增到快取中
            addBitmapToLocalCache(url, bitmap);//將bitmap新增到本地
        }
        return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        super.onPostExecute(bitmap);
        ImageView imageView = (ImageView) listView.findViewWithTag(url);
        if (imageView != null && bitmap != null) {
            imageView.setImageBitmap(bitmap);
        }
        tasks.remove(this);
    }
}

/**
 * 開啟網路請求
 * 根據url來獲取bitmap
 */
private Bitmap getBitmapFromUrl(String urlString) {

    Bitmap bitmap = null;
    HttpURLConnection connection = null;
    try {
        URL mUrl = new URL(urlString);
        connection = (HttpURLConnection) mUrl.openConnection();
        bitmap = BitmapFactory.decodeStream(connection.getInputStream());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (connection != null) {
            connection.disconnect();
        }
    }
    return bitmap;
}

 這樣三級快取就寫好了,相應的載入方法如下:

        //優先從記憶體獲取圖片,若不存在則從本地獲取
        Bitmap bitmap = getBitmapFromLruCache(imgUrl);
        if (bitmap == null) {
            bitmap = getBitmapFromLocalCache(imgUrl);
        }
        //若bitmap存在,直接設定
        if (imageView != null && bitmap != null) {
            imageView.setImageBitmap(bitmap);
        } else {
            //若不存在,開啟執行緒從網路下載
            imgAsyncTask mTask = new imgAsyncTask(imgUrl);
            mTask.execute(imgUrl);
            tasks.add(mTask);
        }

相關推薦

Android學習筆記——圖片三級快取

圖片三級快取的重要性  很多時候我們都需要從網路上下載圖片,如果在圖片很多的情況下,每次啟動app都要從網上下載,就會造成流量的浪費,影響使用者的體驗。因此,要利用快取來避免圖片的重複載入。 圖片快取方式  所謂三級快取,即: 網路快取 記憶體快取

Android學習筆記

1.Android的APK瘦身方法 在這裡給大家推薦一個網站,關於圖片線上壓縮的TinyPNG,然後使用android studio自帶工具Lint剔除無用資源(res資原始檔),如果你閒的話那就再手

Pro Android學習筆記——ContentProvider

上一章講解了ContentProvider的一些基本概念和涉及到的知識。這一章就來實現它。 要實現ContentProvider,我們繼承自ContentProvider這個抽象類,實現其中的抽象方法就可以了,其中的抽象方法包括: query insert update delete g

Android學習筆記--ViewPager的使用輪播功能的實現

是否覺得只有幾個按鈕和幾個View有點太單一呢,頁面上怎麼能只顯示這麼少的內容呢?沒關係,ViewPager來幫忙。(聽說已經過時,但還是看一下吧,總是相通的)這裡是參考了《第一行程式碼》一書。 先上程式碼。 MainActivity.java pac

Android學習筆記5——可通用的介面卡

 本文內容參考自慕課網。  ListView、GridView 是我們在 Android 中很常用的控制元件,通常來說,對於每一個控制元件都要寫對應的 ViewHolder 和 Adapter。但是當專案中的 ListView 很多時,寫 ViewHolder

安卓開發學習筆記Android Stuidio無法引用Intent來創建對象,出現cannot resolve xxx

編譯器 port stact 消失 click first 紅色 xxx font 筆者在進行安卓開發時,發現自己的代碼語法完全沒有問題。尤其是創建intent對象的時候,語法完全是正確的,但是Android Stuidio卻顯示報錯,Intent類顯示為紅色,如圖所示:

Android學習筆記 輸入法

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Android學習筆記 有趣的widget-日期和時間

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Android學習筆記 多頁顯示-SlidingDrawer的使用

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

自動化構建Android專案 ---- Jenkins自動化部署學習筆記

  上篇文章跟大家分享了在Windows上安裝Jenkins的方法,這篇文章來跟大家分享一下利用Jenkins自動化構建Android專案: 一、所需準備: Android專案上傳至版本管理平臺,這裡我準備了Github上的Android專案https://github.co

Pro Android學習筆記 使用者介面和控制16 GridLayout

網格佈局:GridLayout我個人覺得GridLayout的設計還不很完善,每個網格的大小,由填充的cell決定,即預設是wrap很容易整個GridLayout超出螢幕。下面是一個例子:<?xml version="1.0" encoding="utf-8"?><GridLayout xm

Android百度地圖開發學習筆記之定位當前位置和自定義控制元件返回

在完成HelloMap後,接來完成的重要功能是如何定位當前位置和如何一鍵返回。效果圖如下: 這裡的控制元件就是一個ImageView,自己去百度一個好看的圖片就可以了。 一 定位當前位置和自定義控制元件返回 1.官方技術文件 可以先點選百度地圖定位技術文件,仔細看一下相關

Android-Universal-Image-Loader 學習筆記載入圖片原理

public void displayImage(String uri, ImageAware imageAware, DisplayImageOptions options, ImageLoadingListener listener, ImageLoadingProgressListener pro

Pro Android學習筆記:使用者介面和控制13:LinearLayout和TableLayout

佈局Layout Layout是容器,用於對所包含的view進行佈局。layout是view的子類,所以可以作為view嵌入到其他的layout中。Android的layout有LinearLayout、TableLayout,RelativeLayout、FrameLayout、GridLayout。 線

Android電商專案學習筆記--主介面完成

本專案來源於慕課網Android實戰課——Android通用框架設計與完整電商開發 前天跟隨視訊完成了對主介面的封裝及使用,這種模式使用的還不夠熟悉,需加強理解並練習。寫下這篇來加深理解。 先上效果圖: 哈哈,別想多,就是我們平常見的效果。底部

php laravel框架學習筆記 數據庫操作

true 數據 mar sql show top 一行 ati del 原博客鏈接:http://www.cnblogs.com/bitch1319453/p/6810492.html mysql基本配置 你可用通過配置環境變量,使用cmd進入mysql,當然還有一種東

java學習筆記圖形用戶接口

star strong per getwidth cep runnable graphics s2d gb2 這個學期主要放在ACM比賽上去了,比賽結束了。不知不覺就15周了,這周就要java考試了,復習一下java吧。java的學習的目的還是讓我們學以致用,讓我們可以

數據結構學習筆記 線性表的順序存儲和鏈式存儲

出錯 初始化 node != test span 輸入 des val 線性表:由同類型數據元素構成有序序列的線性結構  --》表中元素的個數稱為線性表的長度  --》沒有元素時,成為空表  --》表起始位置稱表頭,表結束位置稱表尾 順序存儲:    1 package

Memcache 學習筆記---- PHP 腳本操作 Memcache 服務器

ext status ram var_dump 介紹 修改 memcache local dbn    PHP 腳本操作 Memcache 服務器 一、PHP腳本操作Memcache方法     使用 PHP 腳本操作 Memcache,在 PHP 手冊中有詳細的介紹,我們

javascript學習筆記:定義函數、調用函數、參數、返回值、局部和全局變量

兩個 cnblogs bsp 結果 value ava ase com 調用 定義函數、調用函數、參數、返回值 關鍵字function定義函數,格式如下: function 函數名(){ 函數體 } 調用函數、參數、返回值的規則和c語言規則類似。 1 <!DOC