您好,登錄后才能下訂單哦!
學習谷歌文檔,總結如下:
1.圖片加載框架的封裝
1)利用HttpURLConnection來封裝網絡加載圖片的方法
2)創建自定義的AsyncTask來封裝1)中加載網絡圖片的方法,并顯示到控件上。
3)暴露方法封裝2)中自定義的加載并顯示圖片的AsyncTask
走完上面這幾步,只需調用一個方法,就可以從網絡上加載一張圖片并且顯示到控件上了。
解決List并發下載圖片錯位的問題
但是,谷歌文檔中說上面代碼會存在一個問題。就是如果在List里使用,復用的話,可能會發生圖
圖片錯位的問題:就是某個item顯示的圖片,可能顯示的圖片是之前的item的圖片。因為之前的這
張圖片可能加載時間比較長,滑動后p_w_picpathview是復用的,所以后面的item可能會顯示之前的item的
圖片。
這種就是由于并發產生的問題,谷歌工程師是這么解決問題的:
1》定義一個類 class DownloadedDrawable extends ColorDrawable,然后將下載的異步任務
DownloadAsyncTask與其綁定起來。
public static void display(Context context,String url, ImageView p_w_picpathView) { Bitmap bitmapFromMemCache = LruCacheUtil.getBitmapFromMemCache(url); if(bitmapFromMemCache != null){ p_w_picpathView.setImageBitmap(bitmapFromMemCache); }else{ if (cancelPotentialDownload(url, p_w_picpathView)) { BitmapDownloaderTask task = new BitmapDownloaderTask(context,p_w_picpathView); DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task); p_w_picpathView.setImageDrawable(downloadedDrawable); task.execute(url); } } }
2》定義2個方法
BitmapDownloaderTask getBitmapDownloaderTask(ImageView p_w_picpathView)
--得到與ImageView綁定的異步下載任務
public static BitmapDownloaderTask getBitmapDownloaderTask(ImageView p_w_picpathView) { if (p_w_picpathView != null) { Drawable drawable = p_w_picpathView.getDrawable(); if (drawable instanceof DownloadedDrawable) { DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable; return downloadedDrawable.getBitmapDownloaderTask(); } } return null; }
boolean cancelPotentialDownload(String url, ImageView p_w_picpathView)
--取消可能正在進行的下載,并返回是否已經取消。
如果與p_w_picpathView綁定的下載任務不為空,再判斷與ImageView綁定的異步下載任務的URL,如果
為null或者是與當前方法傳遞進來URL不一致,說明異步下載任務正在執行之前的下載,就取消任
務,否則說明任務正在執行中且url一致,就不重新開啟任務。
private static boolean cancelPotentialDownload(String url, ImageView p_w_picpathView) { BitmapDownloaderTask bitmapDownloaderTask = BitmapDownloaderTask.getBitmapDownloaderTask(p_w_picpathView); if (bitmapDownloaderTask != null) { String bitmapUrl = bitmapDownloaderTask.url; if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) { bitmapDownloaderTask.cancel(true); } else { // The same URL is already being downloaded. return false; } } return true; }
解決圖片緩存的問題
1》用內存來緩存,使用LruCache這個類。
內存的特點:
內存加載速度比較快,但是內存在開關機之后會被回收,緩存的數據會消失。
底層:
LinkedHashMap來實現存儲
實現原理:
當從url下載圖片之前,先判斷緩存中存不存在圖片,如果存在直接加載圖片,不存在則
去網絡請求圖片。
當AsyncTask下載完圖片之后,如果不為null,就存放到緩存中。
于是我寫了個工具類LruCacheUtils來完成圖片的緩存
public class LruCacheUtil { //LruCache for bitmap private static LruCache<String, Bitmap> mMemoryCache; static { // Get max available VM memory, exceeding this amount will throw an // OutOfMemory exception. Stored in kilobytes as LruCache takes an // int in its constructor. final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); // Use 1/8th of the available memory for this memory cache. final int cacheSize = maxMemory / 8; mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) @Override protected int sizeOf(String key, Bitmap bitmap) { // The cache size will be measured in kilobytes rather than // number of items. return bitmap.getByteCount() / 1024; } }; } public static void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (getBitmapFromMemCache(key) == null) { mMemoryCache.put(key, bitmap); } } public static Bitmap getBitmapFromMemCache(String key) { return mMemoryCache.get(key); } }
2》使用磁盤(Disk)來緩存,使用DiskLruCache(這個類google文檔里并沒有提供)
Android DiskLruCache 源碼解析 硬盤緩存的絕佳方案
http://blog.csdn.net/lmj623565791/article/details/47251585
下載鏈接
http://http://www.oschina.net/p/disklrucache
Android本地緩存DiskLruCache完整詳細學習示例
http://www.2cto.com/kf/201501/368172.html
雖然利用內存來緩存,加載圖片的時候速度比較快,但是像GridView會很快地占滿內存。當應
用非正常關閉(如被電話應用打斷、運行在后臺的時候被殺死)會導致cache被銷毀清空。
注意:獲取圖片應該在后臺進行
Of course, fetching p_w_picpaths from disk is slower than loading from memory and should be done in a
background thread, as disk read times can be unpredictable.(from google doc)
緩存位置:
有外部存儲設備就存放到外部存儲設備中,否則存放到應用包名目錄下。
2.布局優化
sdk下的一些工具并不是專門針對Eclipse的,Android Studio也可以使用。
sdk/tools下的工具Hierarchy Viewer
http://wear.techbrood.com/training/improving-layouts/optimizing-layout.html#Inspect
爽處1:可以查看布局結構某個節點的3個方法Measure、Layout、Draw執行所需要的時間,這樣
如果某個item的加載時間比較長,你就應該要優化了。
使用這個工具可能會遇到的問題:
問題:使用Hierarchyviewer,measure、layout、draw時間未顯示?
解決辦法:點擊菜單 Profile Node,重新加載之后就有了
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。