轉載請注明出處:http://blog.csdn.net/guolin_blog/article/details/34093441
在上一篇文章當中,我們學習了DiskLruCache的概念和基本用法,但僅僅是掌握理論知識顯然是不夠的,那么本篇文章我們就來繼續進階一下,看一看在實戰當中應該怎樣合理使用DiskLruCache。還不熟悉DiskLruCache用法的朋友可以先去參考我的上一篇文章?Android DiskLruCache完全解析,硬盤緩存的最佳方案?。
其實,在真正的項目實戰當中如果僅僅是使用硬盤緩存的話,程序是有明顯短板的。而如果只使用內存緩存的話,程序當然也會有很大的缺陷。因此,一個優秀的程序必然會將內存緩存和硬盤緩存結合到一起使用,那么本篇文章我們就來看一看,如何才能將LruCache和DiskLruCache完美結合到一起。
在?Android照片墻應用實現,再多的圖片也不怕崩潰?這篇文章當中,我編寫了一個照片墻的應用程序,但當時只是單純使用到了內存緩存而已,而今天我們就對這個例子進行擴展,制作一個完整版的照片墻。
那我們開始動手吧,新建一個Android項目,起名叫PhotoWallDemo,這里我使用的是Android 4.0的API。然后新建一個libcore.io包,并將DiskLruCache.Java文件拷貝到這個包下,這樣就把準備工作完成了。
接下來首先需要考慮的仍然是圖片源的問題,簡單起見,我仍然是吧所有圖片都上傳到了我的CSDN相冊當中,然后新建一個Images類,將所有相冊中圖片的網址都配置進去,代碼如下所示:
[java]?view plaincopy
public?class?Images?{????????public?final?static?String[]?imageThumbUrls?=?new?String[]?{??????????"https://img-my.csdn.net/uploads/201407/26/1406383299_1976.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383291_6518.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383291_8239.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383290_9329.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383290_1042.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383275_3977.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383265_8550.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383264_3954.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383264_4787.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383264_8243.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383248_3693.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383243_5120.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383242_3127.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383242_9576.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383242_1721.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383219_5806.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383214_7794.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383213_4418.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383213_3557.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383210_8779.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383172_4577.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383166_3407.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383166_2224.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383166_7301.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383165_7197.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383150_8410.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383131_3736.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383130_5094.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383130_7393.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383129_8813.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383100_3554.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383093_7894.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383092_2432.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383092_3071.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383091_3119.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383059_6589.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383059_8814.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383059_2237.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383058_4330.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406383038_3602.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382942_3079.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382942_8125.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382942_4881.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382941_4559.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382941_3845.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382924_8955.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382923_2141.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382923_8437.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382922_6166.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382922_4843.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382905_5804.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382904_3362.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382904_2312.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382904_4960.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382900_2418.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382881_4490.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382881_5935.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382880_3865.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382880_4662.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382879_2553.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382862_5375.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382862_1748.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382861_7618.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382861_8606.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382861_8949.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382841_9821.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382840_6603.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382840_2405.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382840_6354.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382839_5779.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382810_7578.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382810_2436.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382809_3883.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382809_6269.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382808_4179.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382790_8326.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382789_7174.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382789_5170.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382789_4118.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382788_9532.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382767_3184.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382767_4772.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382766_4924.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382766_5762.jpg",??????????"https://img-my.csdn.net/uploads/201407/26/1406382765_7341.jpg"??????};??}?? 設置好了圖片源之后,我們需要一個GridView來展示照片墻上的每一張圖片。打開或修改activity_main.xml中的代碼,如下所示:
[html]?view plaincopy
<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>?? 很簡單,只是在LinearLayout中寫了一個GridView而已。接著我們要定義GridView中每一個子View的布局,新建一個photo_layout.xml布局,加入如下代碼:
[html]?view plaincopy
<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>?? 仍然很簡單,photo_layout.xml布局中只有一個ImageView控件,就是用它來顯示圖片的。這樣我們就把所有的布局文件都寫好了。
?
接下來新建PhotoWallAdapter做為GridView的適配器,代碼如下所示:
[java]?view plaincopy
public?class?PhotoWallAdapter?extends?ArrayAdapter<String>?{????????????private?Set<BitmapWorkerTask>?taskCollection;????????????private?LruCache<String,?Bitmap>?mMemoryCache;????????????private?DiskLruCache?mDiskLruCache;????????????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;??????????????????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();??????????????}??????????????????????????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.setTag(url);??????????imageView.setImageResource(R.drawable.empty_photo);??????????loadBitmaps(imageView,?url);??????????return?view;??????}????????????public?void?addBitmapToMemoryCache(String?key,?Bitmap?bitmap)?{??????????if?(getBitmapFromMemoryCache(key)?==?null)?{??????????????mMemoryCache.put(key,?bitmap);??????????}??????}????????????public?Bitmap?getBitmapFromMemoryCache(String?key)?{??????????return?mMemoryCache.get(key);??????}????????????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);??????????????}??????????}??????}????????????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;??????}????????????public?void?setItemHeight(int?height)?{??????????if?(height?==?mItemHeight)?{??????????????return;??????????}??????????mItemHeight?=?height;??????????notifyDataSetChanged();??????}????????????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;??????}????????????????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();??????}????????????class?BitmapWorkerTask?extends?AsyncTask<String,?Void,?Bitmap>?{????????????????????private?String?imageUrl;????????????@Override??????????protected?Bitmap?doInBackground(String...?params)?{??????????????imageUrl?=?params[0];??????????????FileDescriptor?fileDescriptor?=?null;??????????????FileInputStream?fileInputStream?=?null;??????????????Snapshot?snapShot?=?null;??????????????try?{??????????????????????????????????final?String?key?=?hashKeyForDisk(imageUrl);??????????????????????????????????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();??????????????????????????}??????????????????????}??????????????????????????????????????????snapShot?=?mDiskLruCache.get(key);??????????????????}??????????????????if?(snapShot?!=?null)?{??????????????????????fileInputStream?=?(FileInputStream)?snapShot.getInputStream(0);??????????????????????fileDescriptor?=?fileInputStream.getFD();??????????????????}??????????????????????????????????Bitmap?bitmap?=?null;??????????????????if?(fileDescriptor?!=?null)?{??????????????????????bitmap?=?BitmapFactory.decodeFileDescriptor(fileDescriptor);??????????????????}??????????????????if?(bitmap?!=?null)?{??????????????????????????????????????????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);??????????????????????????ImageView?imageView?=?(ImageView)?mPhotoWall.findViewWithTag(imageUrl);??????????????if?(imageView?!=?null?&&?bitmap?!=?null)?{??????????????????imageView.setImageBitmap(bitmap);??????????????}??????????????taskCollection.remove(this);??????????}????????????????????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的代碼,非常簡單,如下所示:
[java]?view plaincopy
public?class?MainActivity?extends?Activity?{????????????private?GridView?mPhotoWall;????????????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文件,并加入相應的權限,如下所示:
[html]?view plaincopy
<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文件都在這里了,說明我們的硬盤緩存已經成功了。
好了,今天的講解就到這里,有疑問的朋友可以在下面留言。
?
源碼下載,請點擊這里
總結
以上是生活随笔為你收集整理的Android照片墙完整版,完美结合 内存方案 LruCache 和 硬盘方案 DiskLruCache的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。