Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android緩存策略——打造最全的緩存

Android緩存策略——打造最全的緩存

編輯:關於Android編程

前言:

本篇介紹Android中的各種緩存機制和緩存框架,同樣借鑒網上的一些知識總結分享給大家。

HR經常問到的緩存機制?

客戶端緩存機制是android應用開發中非常重要的一項工作了,使用緩存機制不僅可以為客戶節省流量,同時提高了用戶體驗,比如今日頭條的離線模式,就是通過緩存機制實現的,那麼緩存機制分為2種。文字緩存和多媒體文件緩存。

咱們先來說文字緩存:

1、將於服務器交互得到的json數據或者xml數據存入sd卡中,並在數據庫添加該數據的記錄。添加數據庫記錄時,可以提供2個字段,請求到的Url和本地保存後的文件地址,每次加載數據之前都會根據Url在數據庫中檢索。   ps:本段中提到存入sd卡,可能有的小伙伴不知道,這裡說一下~   首先獲取sdcard路徑:
Environment.getExternalStorageDirectory()
判斷sdcard狀態:
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
保存到sd卡: filename 文件名 content內容
public void saveToSDCard(String filename,String content) throws Exception{  
        File file=new File(Environment.getExternalStorageDirectory(), filename);  
        OutputStream out=new FileOutputStream(file);  
        out.write(content.getBytes());  
        out.close();  
    }  
相關權限添加:
  
  
  
  

2、將Json數據解析後裝入List對象中,然後遍歷List,將數據全部寫入相應的數據庫表結構中,以後每次想服務器發起請求之前可以現在數據庫中檢索,如果有直接返回。   ps:這裡沒有保存到文件,是先保存到list>中,寫入數據庫,每次查詢數據庫獲取數據;  

之後就是多媒體_圖片緩存了(本地緩存):

緩存圖片可以根據當前日期、時間為名字緩存到sd卡中的指定圖片緩存目錄,同時數據庫中左相應記錄,記錄辦法可以采用倆個關鍵字段控制,一個字段是該圖片的URL地址,另一個是該字段的圖片本機地址,取圖片時根據URL在數據中檢索,如果沒有則連接服務器下載,下載之後再服務器中做出相應記錄。   ps:如何緩存到sd卡中呢?其實和文字緩存一樣的思路;
/** 保存方法 */
 public void saveBitmap(Bitmap bm, String picName) {
  Log.e(TAG, "保存圖片");
  File f = new File(Environment.getExternalStorageDirectory(), picName);//保存路徑和圖片名稱(上文說的日期和時間可以作為)
  if (f.exists()) {
   f.delete();
  }
  try {
   FileOutputStream out = new FileOutputStream(f);
   bm.compress(Bitmap.CompressFormat.PNG, 90, out);
   out.flush();
   out.close();
   Log.i(TAG, "已經保存");
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }
同樣存入數據庫,檢索數據庫。

他們說的三級緩存:

內存緩存(從內存中獲取圖片顯示)、本地緩存(內存中沒有從sd卡獲取)、網絡緩存(從網絡下載並保存入本地和內存);   ps:從sd卡獲取圖片是放在子線程裡面執行的,否則快速滑屏的話不夠流暢!

這裡我想提一下Lrucache緩存:

核心的類是LruCache (此類在android-support-v4的包中提供) 。這個類非常適合用來緩存圖片, 它的主要算法原理是把最近使用的對象用強引用存儲在 LinkedHashMap 中,並且把最近最少 使用的對象在緩存值達到預設定值之前從內存中移除。  

實現思路:

(1).要先設置緩存圖片的內存大小,基本上設置為手機內存的1/8,
手機內存的獲取方式:int MAXMEMONRY = (int) (Runtime.getRuntime() .maxMemory() / 1024);
(2).LruCache裡面的鍵值對分別是URL和對應的圖片;
(3).重寫了一個叫做sizeOf的方法,返回的是圖片數量。

  它的使用:

1、初始化Lrucache

import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;

/**
 * application
 * @author hao
 *
 */
public class MyApplication extends Application{
	
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
	}
	/**
	 * @description 
	 *
	 * @param context
	 * @return 得到需要分配的緩存大小,這裡用八分之一的大小來做
	 */
	public int getMemoryCacheSize() {
		// Get memory class of this device, exceeding this amount will throw an
		// OutOfMemory exception.
		final int memClass = ((ActivityManager)getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();

		// Use 1/8th of the available memory for this memory cache.
		return 1024 * 1024 * memClass / 8;
	}

}
ps:這個方法可以說就是獲取系統分配緩存的大小/8 說明我們用其中的八分之一來做緩存,建議配置在application裡面,方便調用。

2、初始化類

final int memoryCache = ((KaleApplication) getApplication()).getMemoryCacheSize();
        Log.d(TAG, "cache size = " + memoryCache / 1024 / 1024 + "M");
        mMemoryCache = new LruCache(memoryCache) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // 重寫此方法來衡量每張圖片的大小,默認返回圖片數量。
                return bitmap.getByteCount() / 1024;
            }
        }; // 初始化
  ps:獲取全局配置的內存,我通過緩存的值來初始化了cache對象,然後重寫了sizeOf()方法。(返回數量)

3、添加刪除和添加操作

    /**
     * @description 將bitmap添加到內存中去
     *
     * @param key
     * @param bitmap
     */
    public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
        if (getBitmapFromMemCache(key) == null) {
            mMemoryCache.put(key, bitmap);
        }
    }

    /**
     * @description 通過key來從內存緩存中獲得bitmap對象
     *
     * @param key
     * @return
     */
    private Bitmap getBitmapFromMemCache(String key) {
        return mMemoryCache.get(key);
    }

4、從網絡上緩存並添加入緩存

	/**
	 * @description 將bitmap加載到imageview中去
	 *
	 * @param resId
	 * @param imageView
	 */
	public void loadBitmapToImageView(String url, ImageView imageView) {
		final Bitmap bitmap = getBitmapFromMemCache("img"); // 先看這個資源在不在內存中,如果在直接讀取為bitmap,否則返回null
		if (bitmap != null) {
			Log.d(TAG, "in memory");
			imageView.setImageBitmap(bitmap);
		} else {
			Log.d(TAG, "not in memory");
			imageView.setImageResource(R.drawable.ic_launcher); // 如果沒有在內存中,先顯示默認的圖片,然後啟動線程去下載圖片
			BitmapWorkerTask task = new BitmapWorkerTask(imageView);
			task.execute(url); // 啟動線程,從網絡下載圖片,下載後加入緩存
		}
	}
ps:判斷圖片是否已經進行了緩存操作。圖片如果在內存中就直接賦值,沒有啟動線程重新獲取。
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;

public class BitmapWorkerTask extends AsyncTask{

	private MainActivity mActivity;
	private ImageView mImageView;
	
	public BitmapWorkerTask(ImageView imageView) {
		mImageView = imageView;
		mActivity = (MainActivity) imageView.getContext();
	}
	
	/**
	 * 下載圖片
	 */
	@Override
	protected Bitmap doInBackground(String... params) {
		Bitmap bitmap = null;  
        HttpURLConnection con = null;  
        try {  
            URL url = new URL(params[0]);  
            con = (HttpURLConnection) url.openConnection();  
            con.setConnectTimeout(10 * 1000);  
            con.setReadTimeout(10 * 1000);  
            bitmap = BitmapFactory.decodeStream(con.getInputStream());  
            //添加到內存
            mActivity.addBitmapToMemoryCache("img", bitmap);
        } catch (MalformedURLException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            if (con != null) {  
                con.disconnect();  
            }  
        } 
		return bitmap;
	}
	
	@Override
	protected void onPostExecute(Bitmap result) {
		super.onPostExecute(result);
		if (result != null) {
			mImageView.setImageBitmap(result); 
		}
	}
}
ps:得到後將bitmap放入緩存中,最後在imageview中展示。 讓我們最後看一下效果吧!!! -------------------csdn服務器維護---------------最後再補充! 點擊下載圖片,小機器人加載中,然後下載從網絡下載成功!再次點擊則不會加載,從內存中獲取!

結束語:

我所了解的緩存到這裡就說完了,後續肯定還會有補充,也希望你多幫我提一些好的想法。
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved