中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Thinking in Google Doc-圖片框架的實現及布局優化

發布時間:2020-06-03 14:53:06 來源:網絡 閱讀:499 作者:屠夫章哥 欄目:移動開發

學習谷歌文檔,總結如下:


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,重新加載之后就有了 

用Hierarchyviewer,measure、layout、draw時間未顯示? 

         

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

寿阳县| 庆云县| 汝阳县| 久治县| 黎城县| 固安县| 五峰| 西乡县| 婺源县| 休宁县| 临洮县| 大悟县| 庆元县| 东方市| 明光市| 习水县| 临城县| 聂荣县| 正宁县| 吴桥县| 凤台县| 平南县| 天等县| 隆安县| 年辖:市辖区| 华宁县| 马公市| 买车| 明星| 钦州市| 土默特右旗| 南靖县| 海林市| 花莲市| 洛宁县| 杭锦后旗| 韩城市| 吉水县| 麦盖提县| 开平市| 珲春市|