BitmapFun解析

  • 若是圖片資源是靜態的,當咱們要在View上顯示圖片時,只須要簡單的將圖片賦值給ImageView就能夠了,但若是須要瀏覽網絡上的圖片時該如何作呢?有可能圖片很大,有可能網速很慢而且不穩定,這種狀況下該如何增長用戶體驗。Android官方的BitmapFun示例程序已經給了咱們很好的解決方法 - 其實萬變不離其中,仍是採用了提高性能的兩種經常使用方法:異步和緩存。數據庫

     

    很少說咱們先來看BitmapFun的主要類圖:緩存

     

     

    ImageWorker:這個是加載圖片的核心類,建議你們看源代碼從這個類看起。它的主要功能是從內存/磁盤緩存中加載圖片,或者是從網絡上下載。這裏第一要使用緩存,第二從網絡上下載,必然要使用異步線程,因此這裏從類圖中你們也能夠看到它有兩個關聯類BitmapWorkerTask(繼承自AsynTask)和ImageCache, 分別用來處理異步和緩存。網絡

     

    ImageWorker提供給外部的主要接口是loadImage方法 - 加載圖片,若是內存中有,直接加載。不然使用異步線程(BitmapWorkerTask)後臺加載 - 從磁盤或者是網絡上下載異步

     

     public void loadImage(Object data, ImageView imageView) {}async

     

     

    BitmapWorkerTask: 異步處理圖片 - 下載並綁定圖片ide

     

    ImageCache: 圖片的緩存處理,這裏使用了二級緩存: 內存和磁盤。這裏從類圖也能夠看到它有一個關聯類DiskLruCache。性能

     

    DiskLruCache: 關於這個類網上有一些詳盡的解釋文章。在看這個類時切忌一開始就看代碼,必定要先看類的說明,主要是journal file的格式,不然你就很難明白它的一些代碼爲何那麼寫。這裏把幾個重點提一下,相信你們再看代碼會容易的多線程

     

      1 前5行是固定(最開始是固定的5行,值是可變)設計

     

      2 一條記錄用類Entry來描述,一條記錄就是一個Entry實例, 好比 CLEAN 3400330d1dfc7f3f7f4b8d4d803dfcf6 832 21054 在程序中就是一個Entry實例3d

     

      3 Editor是Entry的操做器,用來讀寫數據

     

     

         *     libcore.io.DiskLruCache

         *     1

         *     100

         *     2

         *

         *     CLEAN 3400330d1dfc7f3f7f4b8d4d803dfcf6 832 21054

         *     DIRTY 335c4c6028171cfddfbaae1a9c313c52

         *     CLEAN 335c4c6028171cfddfbaae1a9c313c52 3934 2342

         *     REMOVE 335c4c6028171cfddfbaae1a9c313c52

         *     DIRTY 1ab96a171faeeee38496d8b330771a7a

         *     CLEAN 1ab96a171faeeee38496d8b330771a7a 1600 234

         *     READ 335c4c6028171cfddfbaae1a9c313c52

         *     READ 3400330d1dfc7f3f7f4b8d4d803dfcf6

         *

     

     

    寫到這裏先停一下,咱們再次說明ImageWorker的功能,從內存直接加載或異步加載(從磁盤緩存或網絡下載)圖片。緩存的實現-ImageCache, 異步加載的實現 - BitmapWorkerTask。是否是比較清晰了。

     

     

     

    接下來繼續往下看:

     

    ImageResizer:繼承自ImageWorker,可能有的童鞋會問ImageWorker不是已經實現異步和緩存了嗎,這個類是幹嗎的呢?這個主要是根據給定的大小對Image作調整。好比當圖片太大時,不能簡單的加載到內存,須要作大小調整處理。

     

    這裏對它的幾個主要接口說明一下:

     

      setImageSize:設置圖片要調整的大小

     

      calculateInSampleSize: 計算縮放比例 - 根據原圖大小和要調整後的大小計算

     

      decodeSampledBitmapFrom***:獲得調整大小後的圖片,,這裏好幾個方法,數據源不同而已,沒啥大區別。

     

     

     

    ImageFetcher:繼承自ImageResizer。從網絡下載圖片。這裏要澄清一點,processBitmap在ImageWorker中是一個抽象方法,並無實現體,在本示例中,是在ImageFetcher中實現的。之因此這樣設計,是由於圖片的來源是不肯定和可變的,有可能從網絡下載,有可能從本地數據庫獲取。

     

        protected abstract Bitmap processBitmap(Object data);

     

     

     最後就是在View這一層如何來使用了,從類圖中能夠看出,View這一層基本上操做ImageFetcher就能夠了。以IamgeGridFragment爲例:

     

    1 在onCreate中實例化ImageFetcher,而且添加緩存處理實例

     

     

    @Override

        public void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            // The ImageFetcher takes care of loading images into our ImageView children asynchronously

            mImageFetcher = new ImageFetcher(getActivity(), mImageThumbSize);

            mImageFetcher.setLoadingImage(R.drawable.empty_photo);

            mImageFetcher.addImageCache(getActivity().getSupportFragmentManager(), cacheParams);

        }

     

    2 onCreateView中異步加載圖片

     

     @Override

        public View onCreateView(

               

            mGridView.setAdapter(mAdapter);

       }      

    ImageAdapter.getView - 調用ImageFetcher.loadImage加載圖片

     

    @Override

            public View getView(int position, View convertView, ViewGroup container) {

                mImageFetcher.loadImage(Images.imageThumbUrls[position - mNumColumns], imageView);

                return imageView;

            }

    3 在destroty時候關閉緩存

     

    @Override

        public void onDestroy() {

            super.onDestroy();

            mImageFetcher.closeCache();

相關文章
相關標籤/搜索