1. 程式人生 > >Android面試題(23)-圖片的三級快取工具類

Android面試題(23)-圖片的三級快取工具類

上一篇部落格已經把三級快取原理大致都講了,這篇部落格就僅僅貼一下封裝好的一個圖片三級快取工具類,程式碼內有註釋,僅僅小記一下:

首先是MyBitmapUtils,它提供了一個display方法去供外界呼叫:

/**
 * 圖片三級快取工具類
 * Created by PDD on 2018/3/6.
 */
public class MyBitmapUtils {

    private NetWorkCacheUtils netWorkCacheUtils;
    private MemoryCacheUtils memoryCacheUtils;
    private LocalCacheUtils localCacheUtils
; public MyBitmapUtils(Context context){ localCacheUtils=new LocalCacheUtils(); memoryCacheUtils=new MemoryCacheUtils(); netWorkCacheUtils=new NetWorkCacheUtils(context,memoryCacheUtils,localCacheUtils); } public void display(ImageView ivPic,String url) { //給ImageView設定預設顯示圖片
ivPic.setImageResource(R.drawable.btn_zhifubao); //建立一個bitmap變數,用於接收從各快取拿到的圖片bitmap Bitmap bitmap; //首先從記憶體獲取圖片 bitmap = memoryCacheUtils.getBitmapFromMemory(url); //判斷 if (bitmap != null) { ivPic.setImageBitmap(bitmap); System.out.println("從記憶體中獲取圖片成功"); return; } //從記憶體獲取圖片失敗,再從本地獲取圖片
bitmap = localCacheUtils.getBitmapFromLocal(url); //判斷 if (bitmap!=null){ ivPic.setImageBitmap(bitmap); //將從本地獲取的圖片存到記憶體中 memoryCacheUtils.setBitmapToMemory(url,bitmap); System.out.println("從本地獲取圖片成功"); return; } //如果前兩種方法都無法獲得,那麼最後才從網路中獲取圖片 netWorkCacheUtils.getBitmapFromNet(ivPic,url); } }

三級快取之網路快取NetWorkCacheUtils,使用HttpUrlConnection

/**
 * 三級快取值網路快取
 */
public class NetWorkCacheUtils {
    private MemoryCacheUtils memoryCacheUtils;
    private LocalCacheUtils localCacheUtils;
    private Context context;
    public NetWorkCacheUtils(Context context,MemoryCacheUtils memoryCacheUtils, LocalCacheUtils localCacheUtils){
        this.memoryCacheUtils=memoryCacheUtils;
        this.localCacheUtils=localCacheUtils;
        this.context=context;
}

    /**
     * 從網路中下載圖片
     * @param ivPic 需要顯示圖片的ImageView
     * @param url
*/
public void getBitmapFromNet(ImageView ivPic, String url) {
       new BitmapTask().execute(ivPic,url);
}

    class BitmapTask extends AsyncTask<Object,Void,InputStream>{
        private ImageView ivPic;
        private String url;
@Override
protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
}

        @Override
protected void onPostExecute(InputStream inputStream) {
            if (inputStream!=null){
                BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize=2;
options.inPreferredConfig= Bitmap.Config.ARGB_4444;
Bitmap bitmap=BitmapFactory.decodeStream(inputStream,null,options);
ivPic.setImageBitmap(bitmap);
System.out.println("從網路中獲取圖片成功");
//儲存在本地
localCacheUtils.setBitmapToLocal(context,url,inputStream);
//儲存在快取
memoryCacheUtils.setBitmapToMemory(url,bitmap);
}
        }

        @Override
protected InputStream doInBackground(Object... params) {
            ivPic= (ImageView) params[0];
url= (String) params[1];
            return downLoadBitmap(url);
}
    }

    private InputStream downLoadBitmap(String url) {
        HttpURLConnection connection=null;
        try {
            connection=(HttpURLConnection)new URL(url).openConnection();
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
connection.setRequestMethod("GET");
            int responseCode=connection.getResponseCode();
            if (responseCode==200){
                return connection.getInputStream();
}
        } catch (Exception e) {
            e.printStackTrace();
}finally {
            connection.disconnect();
}
        return null;
}

}

三級快取之記憶體快取MemoryCacheUtils,使用LruCache

public class MemoryCacheUtils {

    private LruCache<String,Bitmap> lruCache;
    public MemoryCacheUtils(){
        //獲取手機最大記憶體的1/8
long memory=Runtime.getRuntime().maxMemory()/8;
lruCache=new LruCache<String, Bitmap>((int)memory){
            @Override
protected int sizeOf(String key, Bitmap value) {
                return value.getByteCount();
}
        };
}

    /**
     * 從記憶體中讀圖片
     * @param url
* @return
*/
public  Bitmap getBitmapFromMemory(String url) {
        Bitmap bitmap = lruCache.get(url);
        return bitmap;
}

    public void setBitmapToMemory(String url, Bitmap bitmap) {
        lruCache.put(url,bitmap);
}
}

三級快取之本地快取LocalCacheUtils,使用DiskLruCache

public class LocalCacheUtils {
    DiskLruCache mDiskLruCache = null;
    private DiskLruCache getDiskLruCache(Context context){
        try {
            File cacheDir = getDiskCacheDir(context, "bitmap");
            if (!cacheDir.exists()) {
                cacheDir.mkdirs();
}
            mDiskLruCache = DiskLruCache.open(cacheDir, getAppVersion(context), 1, 10 * 1024 * 1024);
} catch (IOException e) {
            e.printStackTrace();
}
        return mDiskLruCache;
}

    public Bitmap getBitmapFromLocal(String url) {
        try {
            DiskLruCache.Snapshot snapShot = mDiskLruCache.get(getMD5String(url));
            if (snapShot != null) {
                InputStream is = snapShot.getInputStream(0);
Bitmap bitmap = BitmapFactory.decodeStream(is);
                return bitmap;
}
        } catch (IOException e) {
            e.printStackTrace();
}
        return null;
}


    public void setBitmapToLocal(Context context,String url, InputStream inputStream) {
        BufferedOutputStream out = null;
BufferedInputStream in = null;
        try {
            DiskLruCache.Editor editor = getDiskLruCache(context).edit(getMD5String(url));
            if (editor != null) {
                OutputStream outputStream = editor.newOutputStream(0);
in = new BufferedInputStream(inputStream, 8 * 1024);
out = new BufferedOutputStream(outputStream, 8 * 1024);
                int b;
                while ((b = in.read()) != -1) {
                    out.write(b);
}
                editor.commit();
}
            mDiskLruCache.flush();
} catch (IOException e) {
            e.printStackTrace();
}
    }

    public File getDiskCacheDir(Context context, String uniqueName) {
        String cachePath;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) {
            cachePath = context.getExternalCacheDir().getPath();
} else {
            cachePath = context.getCacheDir().getPath();
}
        return new File(cachePath + File.separator + uniqueName);
}

    public int getAppVersion(Context context) {
        try {
            PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            return info.versionCode;
} catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
}
        return 1;
}

    public String getMD5String(String key) {
        String cacheKey;
        try {
            final MessageDigest mDigest = MessageDigest.getInstance("MD5");
mDigest.update(key.getBytes());
cacheKey = bytesToHexString(mDigest.digest());
} catch (NoSuchAlgorithmException e) {
            cacheKey = String.valueOf(key.hashCode());
}
        return cacheKey;
}

    private String bytesToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(0xFF & bytes[i]);
            if (hex.length() == 1) {
                sb.append('0');
}
            sb.append(hex);
}
        return sb.toString();
}
}

相關推薦

Android試題23-圖片三級快取工具

上一篇部落格已經把三級快取原理大致都講了,這篇部落格就僅僅貼一下封裝好的一個圖片三級快取工具類,程式碼內有註釋,僅僅小記一下:首先是MyBitmapUtils,它提供了一個display方法去供外界呼叫:/** * 圖片三級快取工具類 * Created by PDD o

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

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

android 試題

程序 一個 如果 intent傳值 存儲 新的 有一個 數據類型 andro 1、Android中真實寬高,getWidth和getMeasuredWidth的區別:哪個計算的是真實的寬? getWidth():得到的是View在父Layout中布局好後的寬度值,如果沒有父

整理一些常見的java及android試題2

                1. 什麼是Activity?四大元件之一,一般的,一個使用者互動介面對應一個activity, activity 是Context的子類,同時實現了window.callback和keyevent.callback, 可以處理與窗體使用者互動的事件. 我開發常用的的有List

Android試題31-App啟動流程

先貼個連結,總結的挺全面 在看這篇文章之前,希望先看完我的之前的部落格 android面試(6)-Binder機制,因為關於App啟動流程設計很多Binder通訊; 先將“三個程序”,“六個大類”進行介紹: 三個程序: Launcher程序:整個App啟動流程的起點,

Android試題5

1. Android的自動恢復功能是什麼? 恢復備份設定和資料來重新安裝程式 2. Handler是執行緒與Activity通訊的橋樑,將任務執行緒放入佇列裡面派對執行;

Android試題27-android的事件分發機制

今天開始寫一點關於view的知識,先從最基本的講吧,android的事件分發機制,其實在我看來,android的事件分發機制在現實生活中經常能看到,所以我覺得還是很好理解的;先看看生活中常見的一種情形吧;比如說,現在你所在的公司中有一項任務被派發下來了,專案經理把專案交給你的

android試題2——Fragment篇

1、Fragment為什麼被稱為第五大元件 Fragment比Activity更節省記憶體,其切換模式也更加舒適,使用頻率不低於四大元件,且有自己的生命週期,而且必須依附於Activity 2、Activity建立Fragment的方式 靜態建立 動態建立 3、Fragme

Android試題22-lruCache與DiskLruCache快取詳解

關於lruCache(最近最少使用)的演算法,這是一個比較重要的演算法,它的應用非常廣泛,不僅僅在Android中使用,Linux系統等其他地方中也有使用;今天就來看一看這其中的奧祕;講到LruCache,就不得不講一講LinkedHashMap,而對於LinkedHashM

android試題

自己總結了一些android的面試題,先寫一部分,後續在補充 一、Android的四大元件是哪些?它們的作用是? 答:Activity是android程式和使用者互動的介面,相當於單獨的螢幕,需要為保持各介面的狀態做很多持久化的事情,管理生命週期和一些邏輯跳轉。  

Android試題——Activity的生命週期和啟動模式

引言 這份面試題系列文章旨在查漏補缺,通過常見的面試題發現自己在Android基礎知識上的遺漏和欠缺,驗證所學是否紮實。 這是系列的第一章,後面我會根據安卓知識模組分類併網羅分析各種常見面試題。 面試題: Activity的生命週期 答

Android試題24-有關bitmap的操作

有關bitmap的操作一直很多,這裡特此總結一下:public class BitmapTransformUtils { //根據圖片uri生成Bitmap物件 public static Bitmap getBitmapByUrl(Context context,

Android試題28-android的view載入和繪製流程

View的載入流程view佈局一直貫穿於整個android應用中,不管是activity還是fragment都給我們提供了一個view依附的物件,關於view的載入我們在開發中一直使用,在接下來的幾篇文章中將介紹在android中的載入機制和繪製流程並且對於基於android

python3-開發試題python6.23基礎篇2

漢字 2個 特殊 問題 ase 第一個 else () 判斷 1、請至少列舉5個 PEP8 規範(越多越好)。 一、代碼編排 1、縮進。4個空格的縮進,不使用Tap,更不能混合使用Tap和空格 2、每行最大長度79,換行可以使用反斜杠,最好使用圓括號。換行點要在操作符

京東android試題2018 頂級網際網路公司試題系列

以下來自於北京的一個兄弟的面試題 1.靜態內部類和非靜態內部類有什麼區別   2.談談你對java多型的理解   3.如何開啟執行緒,run和runnable有什麼區別   4.執行緒池的好處   5.說一下你知道的設計模式有哪些,介紹下介面卡模式 &n

Android試題2018.11.16

一、UI的繪製過程,常見優化手段以及原理。 二、有幾種常見的單例模式?對於這幾種單例模式synchronized具體鎖的是什麼東西? 三、問記憶體優化你做過沒有?一張十萬乘以十萬的圖片,如何載入才不會記憶體溢位? 四、問記憶體溢位,記憶體抖動,記憶體洩漏你都碰到過嗎?怎麼解決的?如何區分

Android試題文章內容來自他人部落格

騰訊面試題 1.int a = 1; int result = a+++3<<2; 2.int a = 2; int result = (a++ > 2)?(++a):(a+=3); 3.int a = 1234567; int b = 0x06;

python試題

以及 args 空格 代碼實現 spa adding 技術分享 變量作用域 區別 Python中基本數據結構的操作 元組 列表 字典 集合 定義

每天五個java相關試題8--spring篇

ioc 簡單 組件 print 提交數據 常常 spring容器 效果 用戶 首先呢,假設有從事前端開發的大神或者準備從事前端開發的小夥伴無意看到我這篇博客看到這段文字歡迎加我的QQ:【 845415745 】。即將走入社會的菜鳥大學生有關於前端開發的職

java試題

imap 產生 java面試 大型 過程 ets ibm apache服務 廣泛 11、說出Servlet的生命周期,並說出Servlet和CGI的區別? Servlet被服務器實例化後,容器運行其init方法,請求到達時運行其service方法,service方法自動派遣