Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 關於使用LruCache緩存你想緩存的數據

Android 關於使用LruCache緩存你想緩存的數據

編輯:關於Android編程

 

今天我們來一起學習一下緩存技術,相信大家做開發的時候都知道請求網絡數據的重要,但是有一些只用請求一次就過時性的消息比如某些新聞信息,如果我們每次進入新聞界面就從新從網絡上獲取勢必會給用戶帶來不好的體驗,所以我們需要緩存技術來幫我們解決這一問題。

1,LruCache介紹

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

在過去,我們經常會使用一種非常流行的內存緩存技術的實現,即軟引用或弱引用 (SoftReference or WeakReference)。但是現在已經不再推薦使用這種方式了,因為從 Android 2.3 (API Level 9)開始,垃圾回收器會更傾向於回收持有軟引用或弱引用的對象,這讓軟引用和弱引用變得不再可靠。另外,Android 3.0 (API Level 11)中,圖片的數據會存儲在本地的內存當中,因而無法用一種可預見的方式將其釋放,這就有潛在的風險造成應用程序的內存溢出並崩潰。

2,LruCache使用 下面我們就來寫一個簡單的demo來學習LruCache,效果也是每次請求一次第二次直接從緩存中提取出來不用再次請求網絡
/**
	 * 緩存json數據
	 */
	private LruCache mJsonCache;
	/**
	 * 緩存圖片信息
	 */
	private LruCache mBitmapCache;

	public Util() {
		mJsonCache = new LruCache(1 * 1024 * 1024);
		mBitmapCache = new LruCache(2 * 1024 * 1024);
	}

	/**
	 * 添加進入緩存列表
	 * 
	 * @param key
	 * @param value
	 */
	public void addJsonLruCache(Integer key, String value) {
		mJsonCache.put(key, value);
	}

	public void addBitmapLruCache(Integer key, Bitmap value) {
		mBitmapCache.put(key, value);
	}

	/**
	 * 從緩存列表中拿出來
	 * 
	 * @param key
	 * @return
	 */
	public String getJsonLruCache(Integer key) {
		return mJsonCache.get(key);
	}

	public Bitmap getBitmapLruCache(Integer key) {
		return mBitmapCache.get(key);
	}

可以看到我們准備緩存Bitmap與String,只需要拿到信息的時候put進緩存中,需要的時候get出來,是不是非常簡單,我們為我們String分配了1m為我們的Bitmap分配了2m空間,這只是我們的demo為了簡單這樣使用,實際上我們應該更加詳細的考慮到底應該為緩存分配多大的空間
    // 獲取到可用內存的最大值,使用內存超出這個值會引起OutOfMemory異常。 
    // LruCache通過構造函數傳入緩存值,以KB為單位。 
    int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); 
一般來說最大值的1/8左右就可以了。
public class MainActivity extends Activity implements OnItemClickListener {
	private static final String LIST_DATA = http://api.yi18.net/top/list;
	private ListView mListView;
	private ArrayAdapter mAdapter;
	private ArrayList mListId;
	private Util util;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		util = new Util();
		mListView = (ListView) findViewById(R.id.list);
		mListId = new ArrayList();
		mAdapter = new ArrayAdapter(this,
				android.R.layout.simple_list_item_1);
		mListView.setAdapter(mAdapter);
		mListView.setOnItemClickListener(this);
		new DownLoadJson().execute(LIST_DATA);
	}
這一段就是普通的請求數據添加到ListView中。
private void getJsonData(String json) {
		try {
			JSONObject jsonObject = new JSONObject(json);
			if (jsonObject.getBoolean(success)) {
				JSONArray jsonArray = jsonObject.getJSONArray(yi18);
				for (int i = 0; i < jsonArray.length(); i++) {
					JSONObject jsonObject2 = (JSONObject) jsonArray.opt(i);
					if (i < 5) {
						mAdapter.add(jsonObject2.getString(title));
						mListId.add(jsonObject2.getInt(id));
					}
				}
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	class DownLoadJson extends AsyncTask {

		@Override
		protected String doInBackground(String... params) {
			return util.downLoadJson(params[0]);
		}

		@Override
		protected void onPostExecute(String result) {
			if (result != null) {
				getJsonData(result);
			}
		}

	}
data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316065271.png

我們就簡單的取了前五條數據用來模擬我們的新聞,用的是熱點熱詞的Api。

 

3,緩存

 

@Override
	public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) {
		// TODO Auto-generated method stub
		String message = util.getJsonLruCache(mListId.get(arg2));
		Bitmap bitmap = util.getBitmapLruCache(mListId.get(arg2));

		if (message != null) {
			intentNewsInfo(arg2, message, bitmap);
		} else {
			intentNewsInfo(arg2, null, null);
		}

	}

	public void intentNewsInfo(int arg2, String message, Bitmap bitmap) {
		Intent intent = new Intent(MainActivity.this, NewsinfoActivity.class);
		intent.putExtra(message, message);
		intent.putExtra(bitmap, bitmap);
		intent.putExtra(index, arg2);
		intent.putExtra(id, mListId.get(arg2));
		startActivityForResult(intent, 100);
	}

可以看到我們這裡先是查找緩存中是否存在數據如果存在直接傳給新聞詳情界面,如果沒有則在第二個界面獲取再傳回來。

 

 

public class NewsinfoActivity extends Activity {

	private String NEWS_INFO = http://api.yi18.net/top/show?id=;
	private String imageRes[] = {
			http://d.hiphotos.baidu.com/image/h%3D360/sign=405b763459afa40f23c6c8db9b65038c/562c11dfa9ec8a13508c96e6f403918fa0ecc026.jpg,
			http://c.hiphotos.baidu.com/image/h%3D360/sign=798b4f82caea15ce5eeee60f86013a25/9c16fdfaaf51f3dece3f986397eef01f3a297923.jpg,
			http://f.hiphotos.baidu.com/image/h%3D360/sign=20a94e03940a304e4d22a6fce1c9a7c3/ac4bd11373f082028719ab3848fbfbedab641b29.jpg,
			http://b.hiphotos.baidu.com/image/h%3D360/sign=3a1af7349145d688bc02b4a294c37dab/4b90f603738da977c0f5b82cb351f8198718e3db.jpg,
			http://d.hiphotos.baidu.com/image/h%3D360/sign=75e596560f33874483c5297a610ed937/55e736d12f2eb9381891b2f4d6628535e5dd6f3c.jpg };
	private Intent intent;
	private Util util;
	private int newId, index;
	private ImageView imageView;
	private TextView textView;
	private Bitmap bitmap;
	private String message;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_newsinfo);
		intent = getIntent();
		util = new Util();
		imageView = (ImageView) findViewById(R.id.image);
		textView = (TextView) findViewById(R.id.message);
		newId = intent.getExtras().getInt(id);
		index = intent.getExtras().getInt(index);
		if (intent.getExtras().getString(message) != null) {
			message = intent.getExtras().getString(message);
			bitmap = intent.getParcelableExtra(bitmap);
			textView.setText(Html.fromHtml(message));
			imageView.setImageBitmap(bitmap);
			Toast.makeText(this, 沒有訪問網絡哦, 2000).show();
		} else {
			new DownLoadJson().execute(NEWS_INFO + newId);
			new DownLoadBitmap().execute(imageRes[index]);
			Toast.makeText(this, 訪問網絡哦, 2000).show();
		}

	}

	@Override
	public void onBackPressed() {
		Intent dataIntent = new Intent();
		dataIntent.putExtra(message, message);
		dataIntent.putExtra(bitmap, bitmap);
		dataIntent.putExtra(newId, newId);
		setResult(20, dataIntent);
		finish();
		super.onBackPressed();
	}

	private void getJsonData(String json) {
		try {
			JSONObject jsonObject = new JSONObject(json);
			if (jsonObject.getBoolean(success)) {
				JSONObject jsonObject2 = new JSONObject(
						jsonObject.getString(yi18));
				message = jsonObject2.getString(message);
				textView.setText(Html.fromHtml(jsonObject2.getString(message)));
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	class DownLoadJson extends AsyncTask {

		@Override
		protected String doInBackground(String... params) {
			return util.downLoadJson(params[0]);
		}

		@Override
		protected void onPostExecute(String result) {
			if (result != null) {
				getJsonData(result);
			}
		}

	}

	class DownLoadBitmap extends AsyncTask {

		@Override
		protected Bitmap doInBackground(String... params) {
			// TODO Auto-generated method stub
			return util.downLoadBitmap(params[0]);
		}

		@Override
		protected void onPostExecute(Bitmap result) {
			if (result != null) {
				bitmap = result;
				imageView.setImageBitmap(result);
			}
		}
	}

}

這就比較清晰明白了,每次我們都把這個界面獲取到的信息存到LruCache裡面。

 

 

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        int newId = data.getExtras().getInt(newId);
        String message = data.getExtras().getString(message);
        Bitmap bitmap = data.getParcelableExtra(bitmap);
		util.addJsonLruCache(newId, message);
		util.addBitmapLruCache(newId, bitmap);
		super.onActivityResult(requestCode, resultCode, data);
	}

4,效果

 

data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316065254.gif

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved