本機快取
非同步下載
大家都知道,在android應用中UI線程5秒沒響應的話就會拋出無響應異常,對於遠程擷取大的資源來說,這種異常還是很容易就會拋出來的,那麼怎麼避免這種問題的產生。在android中提供兩種方法來做這件事情:
啟動一個新的線程來擷取資源,完成後通過Handler機制發送訊息,並在UI線程中處理訊息,從而達到在非同步線程中擷取圖片,然後通過Handler Message來更新UI線程的過程。
使用android中提供的AsyncTask來完成。
具體的做法這裡就不介紹了,查下API就可以了,或者是google、baidu下。這裡主要來說本機快取。
本機快取
對於圖片資源來說,你不可能讓應用每次擷取的時候都重新到遠程去下載(ListView),這樣會浪費資源,但是你又不能讓所有圖片資源都放到記憶體中去(雖然這樣載入會比較快),因為圖片資源往往會佔用很大的記憶體空間,容易導致OOM。那麼如果下載下來的圖片儲存到SDCard中,下次直接從SDCard上去擷取呢?這也是一種做法,我看了下,還是有不少應用採用這種方式的。採用LRU等一些演算法可以保證sdcard被佔用的空間只有一小部分,這樣既保證了圖片的載入、節省了流量、又使SDCard的空間只佔用了一小部分。另外一種做法是資源直接儲存在記憶體中,然後設定到期時間和LRU規則。
sdcard儲存:
在sdcard上開闢一定的空間,需要先判斷sdcard上剩餘空間是否足夠,如果足夠的話就可以開闢一些空間,比如10M
當需要擷取圖片時,就先從sdcard上的目錄中去找,如果找到的話,使用該圖片,並更新圖片最後被使用的時間。如果找不到,通過URL去download
去伺服器端下載圖片,如果下載成功了,放入到sdcard上,並使用,如果失敗了,應該有重試機制。比如3次。
下載成功後儲存到sdcard上,需要先判斷10M空間是否已經用完,如果沒有用完就儲存,如果空間不足就根據LRU規則刪除一些最近沒有被使用者的資源。
儲存圖片到SD卡上
java代碼:
- private void saveBmpToSd(Bitmap bm, Stringurl) {
- if (bm == null) {
- Log.w(TAG, " trying to savenull bitmap");
- return;
- }
- //判斷sdcard上的空間
- if (FREE_SD_SPACE_NEEDED_TO_CACHE >freeSpaceOnSd()) {
- Log.w(TAG, "Low free space onsd, do not cache");
- return;
- }
- String filename =convertUrlToFileName(url);
- String dir = getDirectory(filename);
- File file = new File(dir +"/" + filename);
- try {
- file.createNewFile();
- OutputStream outStream = newFileOutputStream(file);
- bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
- outStream.flush();
- outStream.close();
- Log.i(TAG, "Image saved tosd");
- } catch (FileNotFoundException e) {
- Log.w(TAG,"FileNotFoundException");
- } catch (IOException e) {
- Log.w(TAG,"IOException");
- }
- }
複製代碼
計算sdcard上的空間:
java代碼:
- /**
- * 計算sdcard上的剩餘空間
- * @return
- */
- private int freeSpaceOnSd() {
- StatFs stat = newStatFs(Environment.getExternalStorageDirectory() .getPath());
- double sdFreeMB = ((double)stat.getAvailableBlocks() * (double) stat.getBlockSize()) / MB;
- return (int) sdFreeMB;
- }
複製代碼
系列之Android 遠程圖片擷取和本機快取(二)的文章連結http://www.eoeandroid.com/thread-98449-1-1.html
系列之Android 遠程圖片擷取和本機快取(三)的文章連結http://www.eoeandroid.com/thread-98450-1-1.html