Android照片牆完整版,的完美結合LruCache和DiskLruCache

轉載請註明出處:http://blog.csdn.net/guolin_blog/article/details/34093441html

在上一篇文章其中,咱們學習了DiskLruCache的概念和基本使用方法。但僅僅是掌握理論知識顯然是不夠的,那麼本篇文章咱們就來繼續進階一下。看一看在實戰其中應該如何合理使用DiskLruCache。java

還不熟悉DiskLruCache使用方法的朋友可以先去參考個人上一篇文章 Android DiskLruCache全然解析,硬盤緩存的最佳方案 。android

事實上,在真正的項目實戰其中假設僅僅是使用硬盤緩存的話,程序是有明顯短板的。而假設僅僅使用內存緩存的話,程序固然也會有很是大的缺陷。所以,一個優秀的程序一定會將內存緩存和硬盤緩存結合到一塊兒使用,那麼本篇文章咱們就來看一看,如何才幹將LruCache和DiskLruCache完美結合到一塊兒。算法

Android照片牆應用實現,再多的圖片也不怕崩潰 這篇文章其中,我編寫了一個照片牆的應用程序,但當時僅僅是單純使用到了內存緩存而已,而今天咱們就對這個樣例進行擴展,製做一個完整版的照片牆。緩存

那咱們開始動手吧。新建一個Android項目,起名叫PhotoWallDemo。這裏我使用的是Android 4.0的API。微信

而後新建一個libcore.io包。並將DiskLruCache.java文件複製到這個包下。這樣就把準備工做完畢了。
網絡

接下來首先需要考慮的仍然是圖片源的問題,簡單起見。我仍然是吧所有圖片都上傳到了個人CSDN相冊其中,而後新建一個Images類,將所有相冊中圖片的網址都配置進去。代碼例如如下所看到的:app

public class Images {

	public final static String[] imageThumbUrls = new String[] {
		"http://img.my.csdn.net/uploads/201407/26/1406383299_1976.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383291_6518.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383291_8239.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383290_9329.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383290_1042.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383275_3977.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383265_8550.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383264_3954.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383264_4787.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383264_8243.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383248_3693.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383243_5120.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383242_3127.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383242_9576.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383242_1721.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383219_5806.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383214_7794.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383213_4418.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383213_3557.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383210_8779.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383172_4577.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383166_3407.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383166_2224.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383166_7301.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383165_7197.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383150_8410.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383131_3736.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383130_5094.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383130_7393.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383129_8813.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383100_3554.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383093_7894.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383092_2432.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383092_3071.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383091_3119.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383059_6589.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383059_8814.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383059_2237.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383058_4330.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406383038_3602.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382942_3079.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382942_8125.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382942_4881.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382941_4559.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382941_3845.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382924_8955.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382923_2141.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382923_8437.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382922_6166.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382922_4843.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382905_5804.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382904_3362.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382904_2312.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382904_4960.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382900_2418.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382881_4490.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382881_5935.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382880_3865.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382880_4662.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382879_2553.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382862_5375.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382862_1748.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382861_7618.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382861_8606.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382861_8949.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382841_9821.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382840_6603.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382840_2405.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382840_6354.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382839_5779.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382810_7578.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382810_2436.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382809_3883.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382809_6269.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382808_4179.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382790_8326.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382789_7174.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382789_5170.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382789_4118.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382788_9532.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382767_3184.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382767_4772.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382766_4924.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382766_5762.jpg",
		"http://img.my.csdn.net/uploads/201407/26/1406382765_7341.jpg"
	};
}
設置好了圖片源以後,咱們需要一個GridView來展現照片牆上的每一張圖片。

打開或改動activity_main.xml中的代碼。例如如下所看到的:異步

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <GridView
        android:id="@+id/photo_wall"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:columnWidth="@dimen/image_thumbnail_size"
        android:gravity="center"
        android:horizontalSpacing="@dimen/image_thumbnail_spacing"
        android:numColumns="auto_fit"
        android:stretchMode="columnWidth"
        android:verticalSpacing="@dimen/image_thumbnail_spacing" >
    </GridView>

</LinearLayout>
很是easy,僅僅是在LinearLayout中寫了一個GridView而已。接着咱們要定義GridView中每個子View的佈局,新建一個photo_layout.xml佈局,加入例如如下代碼:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <ImageView 
        android:id="@+id/photo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true"
        android:scaleType="fitXY"
        />

</RelativeLayout>
仍然很是easy,photo_layout.xml佈局中僅僅有一個ImageView控件,就是用它來顯示圖片的。這樣咱們就把所有的佈局文件都寫好了。

接下來新建PhotoWallAdapter作爲GridView的適配器,代碼例如如下所看到的:ide

public class PhotoWallAdapter extends ArrayAdapter<String> {

	/**
	 * 記錄所有正在下載或等待下載的任務。
	 */
	private Set<BitmapWorkerTask> taskCollection;

	/**
	 * 圖片緩存技術的核心類。用於緩存所有下載好的圖片,在程序內存達到設定值時會將最少近期使用的圖片移除掉。
	 */
	private LruCache<String, Bitmap> mMemoryCache;

	/**
	 * 圖片硬盤緩存核心類。
	 */
	private DiskLruCache mDiskLruCache;

	/**
	 * GridView的實例
	 */
	private GridView mPhotoWall;

	/**
	 * 記錄每個子項的高度。
	 */
	private int mItemHeight = 0;

	public PhotoWallAdapter(Context context, int textViewResourceId, String[] objects,
			GridView photoWall) {
		super(context, textViewResourceId, objects);
		mPhotoWall = photoWall;
		taskCollection = new HashSet<BitmapWorkerTask>();
		// 獲取應用程序最大可用內存
		int maxMemory = (int) Runtime.getRuntime().maxMemory();
		int cacheSize = maxMemory / 8;
		// 設置圖片緩存大小爲程序最大可用內存的1/8
		mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
			@Override
			protected int sizeOf(String key, Bitmap bitmap) {
				return bitmap.getByteCount();
			}
		};
		try {
			// 獲取圖片緩存路徑
			File cacheDir = getDiskCacheDir(context, "thumb");
			if (!cacheDir.exists()) {
				cacheDir.mkdirs();
			}
			// 建立DiskLruCache實例,初始化緩存數據
			mDiskLruCache = DiskLruCache
					.open(cacheDir, getAppVersion(context), 1, 10 * 1024 * 1024);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		final String url = getItem(position);
		View view;
		if (convertView == null) {
			view = LayoutInflater.from(getContext()).inflate(R.layout.photo_layout, null);
		} else {
			view = convertView;
		}
		final ImageView imageView = (ImageView) view.findViewById(R.id.photo);
		if (imageView.getLayoutParams().height != mItemHeight) {
			imageView.getLayoutParams().height = mItemHeight;
		}
		// 給ImageView設置一個Tag,保證異步載入圖片時不會亂序
		imageView.setTag(url);
		imageView.setImageResource(R.drawable.empty_photo);
		loadBitmaps(imageView, url);
		return view;
	}

	/**
	 * 將一張圖片存儲到LruCache中。
	 * 
	 * @param key
	 *            LruCache的鍵。這裏傳入圖片的URL地址。

* @param bitmap * LruCache的鍵。這裏傳入從網絡上下載的Bitmap對象。 */ public void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (getBitmapFromMemoryCache(key) == null) { mMemoryCache.put(key, bitmap); } } /** * 從LruCache中獲取一張圖片,假設不存在就返回null。

* * @param key * LruCache的鍵,這裏傳入圖片的URL地址。 * @return 相應傳入鍵的Bitmap對象。或者null。

*/ public Bitmap getBitmapFromMemoryCache(String key) { return mMemoryCache.get(key); } /** * 載入Bitmap對象。此方法會在LruCache中檢查所有屏幕中可見的ImageView的Bitmap對象, * 假設發現不論什麼一個ImageView的Bitmap對象不在緩存中。就會開啓異步線程去下載圖片。 */ public void loadBitmaps(ImageView imageView, String imageUrl) { try { Bitmap bitmap = getBitmapFromMemoryCache(imageUrl); if (bitmap == null) { BitmapWorkerTask task = new BitmapWorkerTask(); taskCollection.add(task); task.execute(imageUrl); } else { if (imageView != null && bitmap != null) { imageView.setImageBitmap(bitmap); } } } catch (Exception e) { e.printStackTrace(); } } /** * 取消所有正在下載或等待下載的任務。 */ public void cancelAllTasks() { if (taskCollection != null) { for (BitmapWorkerTask task : taskCollection) { task.cancel(false); } } } /** * 依據傳入的uniqueName獲取硬盤緩存的路徑地址。 */ 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 (NameNotFoundException e) { e.printStackTrace(); } return 1; } /** * 設置item子項的高度。 */ public void setItemHeight(int height) { if (height == mItemHeight) { return; } mItemHeight = height; notifyDataSetChanged(); } /** * 使用MD5算法對傳入的key進行加密並返回。 */ public String hashKeyForDisk(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; } /** * 將緩存記錄同步到journal文件裏。

*/ public void fluchCache() { if (mDiskLruCache != null) { try { mDiskLruCache.flush(); } catch (IOException e) { e.printStackTrace(); } } } 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(); } /** * 異步下載圖片的任務。

* * @author guolin */ class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> { /** * 圖片的URL地址 */ private String imageUrl; @Override protected Bitmap doInBackground(String... params) { imageUrl = params[0]; FileDescriptor fileDescriptor = null; FileInputStream fileInputStream = null; Snapshot snapShot = null; try { // 生成圖片URL相應的key final String key = hashKeyForDisk(imageUrl); // 查找key相應的緩存 snapShot = mDiskLruCache.get(key); if (snapShot == null) { // 假設沒有找到相應的緩存。則準備從網絡上請求數據,並寫入緩存 DiskLruCache.Editor editor = mDiskLruCache.edit(key); if (editor != null) { OutputStream outputStream = editor.newOutputStream(0); if (downloadUrlToStream(imageUrl, outputStream)) { editor.commit(); } else { editor.abort(); } } // 緩存被寫入後,再次查找key相應的緩存 snapShot = mDiskLruCache.get(key); } if (snapShot != null) { fileInputStream = (FileInputStream) snapShot.getInputStream(0); fileDescriptor = fileInputStream.getFD(); } // 將緩存數據解析成Bitmap對象 Bitmap bitmap = null; if (fileDescriptor != null) { bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor); } if (bitmap != null) { // 將Bitmap對象加入到內存緩存其中 addBitmapToMemoryCache(params[0], bitmap); } return bitmap; } catch (IOException e) { e.printStackTrace(); } finally { if (fileDescriptor == null && fileInputStream != null) { try { fileInputStream.close(); } catch (IOException e) { } } } return null; } @Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); // 依據Tag找到相應的ImageView控件。將下載好的圖片顯示出來。

ImageView imageView = (ImageView) mPhotoWall.findViewWithTag(imageUrl); if (imageView != null && bitmap != null) { imageView.setImageBitmap(bitmap); } taskCollection.remove(this); } /** * 創建HTTP請求,並獲取Bitmap對象。

* * @param imageUrl * 圖片的URL地址 * @return 解析後的Bitmap對象 */ private boolean downloadUrlToStream(String urlString, OutputStream outputStream) { HttpURLConnection urlConnection = null; BufferedOutputStream out = null; BufferedInputStream in = null; try { final URL url = new URL(urlString); urlConnection = (HttpURLConnection) url.openConnection(); in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024); out = new BufferedOutputStream(outputStream, 8 * 1024); int b; while ((b = in.read()) != -1) { out.write(b); } return true; } catch (final IOException e) { e.printStackTrace(); } finally { if (urlConnection != null) { urlConnection.disconnect(); } try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (final IOException e) { e.printStackTrace(); } } return false; } } }

代碼有點長。咱們一點點進行分析。

首先在PhotoWallAdapter的構造函數中,咱們初始化了LruCache類。並設置了內存緩存容量爲程序最大可用內存的1/8。緊接着調用了DiskLruCache的open()方法來建立實例。並設置了硬盤緩存容量爲10M。這樣咱們就把LruCache和DiskLruCache的初始化工做完畢了。

接着在getView()方法中,咱們爲每個ImageView設置了一個惟一的Tag,這個Tag的做用是爲了後面可以準確地找回這個ImageView,否則異步載入圖片會出現亂序的狀況。而後在getView()方法的最後調用了loadBitmaps()方法,載入圖片的詳細邏輯也就是在這裏運行的了。

進入到loadBitmaps()方法中可以看到,實現是調用了getBitmapFromMemoryCache()方法來從內存中獲取緩存,假設獲取到了則直接調用ImageView的setImageBitmap()方法將圖片顯示到界面上。假設內存中沒有獲取到。則開啓一個BitmapWorkerTask任務來去異步載入圖片。

那麼在BitmapWorkerTask的doInBackground()方法中。咱們就靈活運用了上篇文章中學習的DiskLruCache的各類使用方法。首先依據圖片的URL生成相應的MD5 key。而後調用DiskLruCache的get()方法來獲取硬盤緩存。假設沒有獲取到的話則從網絡上請求圖片並寫入硬盤緩存,接着將Bitmap對象解析出來並加入到內存緩存其中,最後將這個Bitmap對象顯示到界面上,這樣一個完整的流程就運行完了。

那麼咱們再來分析一下上述流程。每次載入圖片的時候都優先去內存緩存其中讀取,當讀取不到的時候則回去硬盤緩存中讀取,而假設硬盤緩存仍然讀取不到的話,就從網絡上請求原始數據。

不管是從硬盤緩存仍是從網絡獲取,讀取到了數據以後都應該加入到內存緩存其中。這種話咱們下次再去讀取圖片的時候就能迅速從內存其中讀取到,而假設該圖片從內存中被移除了的話,那就反覆再運行一遍上述流程就可以了。

這樣咱們就把LruCache和DiskLruCache完美結合到一塊兒了。接下來還需要編寫MainActivity的代碼,很是easy。例如如下所看到的:

public class MainActivity extends Activity {

	/**
	 * 用於展現照片牆的GridView
	 */
	private GridView mPhotoWall;

	/**
	 * GridView的適配器
	 */
	private PhotoWallAdapter mAdapter;

	private int mImageThumbSize;
	private int mImageThumbSpacing;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mImageThumbSize = getResources().getDimensionPixelSize(
				R.dimen.image_thumbnail_size);
		mImageThumbSpacing = getResources().getDimensionPixelSize(
				R.dimen.image_thumbnail_spacing);
		mPhotoWall = (GridView) findViewById(R.id.photo_wall);
		mAdapter = new PhotoWallAdapter(this, 0, Images.imageThumbUrls,
				mPhotoWall);
		mPhotoWall.setAdapter(mAdapter);
		mPhotoWall.getViewTreeObserver().addOnGlobalLayoutListener(
				new ViewTreeObserver.OnGlobalLayoutListener() {
					
					@Override
					public void onGlobalLayout() {
						final int numColumns = (int) Math.floor(mPhotoWall
								.getWidth()
								/ (mImageThumbSize + mImageThumbSpacing));
						if (numColumns > 0) {
							int columnWidth = (mPhotoWall.getWidth() / numColumns)
									- mImageThumbSpacing;
							mAdapter.setItemHeight(columnWidth);
							mPhotoWall.getViewTreeObserver()
									.removeGlobalOnLayoutListener(this);
						}
					}
				});
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		mAdapter.fluchCache();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		// 退出程序時結束所有的下載任務
		mAdapter.cancelAllTasks();
	}

}

上述代碼中,咱們經過getViewTreeObserver()的方式監聽View的佈局事件,當佈局完畢之後。咱們又一次改動一下GridView中子View的高度,以保證子View的寬度和高度可以保持一致。

到這裏尚未結束,最後還需要配置一下AndroidManifest.xml文件,並加入相應的權限。例如如下所看到的:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.photoswalldemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.photoswalldemo.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

好了。所有代碼都在這兒了,讓咱們來運行一下吧。效果例如如下圖所看到的:


第一次從網絡上請求圖片的時候有點慢,但以後載入圖片就會很是快了。滑動起來也很是流暢。

那麼咱們最後再檢查一下這些圖片是否是已經正確緩存在指定地址了。進入 /sdcard/Android/data/<application package>/cache/thumb 這個路徑,例如如下圖所看到的:


可以看到。每張圖片的緩存以及journal文件都在這裏了,說明咱們的硬盤緩存已經成功了。

好了,今天的解說就到這裏,有疑問的朋友可以在如下留言。

源代碼下載,請點擊這裏

第一時間得到博客更新提醒,以及不少其它技術信息分享,歡迎關注個人微信公衆號。掃一掃下方二維碼或搜索微信號guolin_blog,就能夠關注。

相關文章
相關標籤/搜索