Android RecyclerView利用Glide載入大量圖片into(Target)導致OOM異常

來源:互聯網
上載者:User

標籤:ade   cache   設定圖   int   post   help   tag   ide   div   

學過android的人應該都知道Glide是一個無比強大的圖片載入庫,它內部已經提供了很好的緩衝機制供我們選擇,我們只需一個參數調用即可(DiskCacheStrategy()),而不必像Universal-Image-Loader類一樣自己實現。正是因為它太好用了,導致我們很容易忽略一些重要的細節。Android的bitmap對象是最容易導致OOM的元兇之一,如果我們載入大量的bitmap對象,我們就不得不預防OOM。 
  我的原意是想將圖片載入進RecyclerView裡以StaggeredGridLayoutManager模式2列顯示,實現瀑布流效果

mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));

   但是因為圖片都是網路中擷取到的,不知道其具體大小,因此一開始採用target來實現,具體如下:

Glide.with(itemView.getContext())     .load(url)     .asBitmap()     .placeholder(R.drawable.error_pic)     .diskCacheStrategy(DiskCacheStrategy.ALL)     .into(new SimpleTarget<Bitmap>(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) {        @Override        public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {            //原始圖片寬高            int imageWidth = resource.getWidth();            int imageHeight = resource.getHeight();            //按比例收縮圖片            float ratio=(float) ((imageWidth*1.0)/(width*1.0));            int height=(int) (imageHeight*1.0/ratio);            ViewGroup.LayoutParams params = ivImage.getLayoutParams();            params.width=width;            params.height=height;            ivImage.setImageBitmap(resource);        }    });

而在此之前我通過這種方法也確實能夠載入,但載入的都是一些幾十KB的小圖片,也沒有遇到OOM的問題。但是在我現在所做得這個項目中,因為需要載入的圖片的源圖片是MB層級的,所以不能像之前一樣將其載入到bitmap裡。 

  後來想起以前沒用Glide之前有種方法可以不需要載入圖片進bitmap也能擷取到圖片的寬高,便想著能否將其結合著使用。以下為在不載入圖片的情況下擷取圖片寬高的方法:

//在不載入圖片情況下擷取圖片大小public static int[] getImageWidthHeight(String path){    BitmapFactory.Options options = new BitmapFactory.Options();    /**     * 最關鍵在此,把options.inJustDecodeBounds = true;     * 這裡再decodeFile(),返回的bitmap為空白,但此時調用options.outHeight時,已經包含了圖片的高了     */    options.inJustDecodeBounds = true;    Bitmap bitmap = BitmapFactory.decodeFile(path, options); // 此時返回的bitmap為null    /**     *options.outHeight為原始圖片的高     */    return new int[]{options.outWidth,options.outHeight};}

這樣我就擷取到原圖片的寬高了,那麼接下來我就不需要再使用target對象來擷取圖片,而是直接重新設定圖片寬高即可,但在此之前還的將圖片等比例縮放:

//擷取螢幕寬度DisplayMetrics outMetrics = new DisplayMetrics();WindowManager manager=getWindowManager();manager.getDefaultDisplay().getMetrics(outMetrics);width = outMetrics.widthPixels/2;//按寬度等比例縮放,不然會OOMint[] width_height= FileHelper.getImageWidthHeight(NetUrl.dir+"/"+data);float ratio=(float) ((width_height[0]*1.0)/(width*1.0));int height=(int) (width_height[1]*1.0/ratio);

最後直接調用glide重新設定大小即可:

 Glide.with(itemView.getContext())     .load(url)     .asBitmap()     .placeholder(R.drawable.error_pic)     .diskCacheStrategy(DiskCacheStrategy.RESULT)     .override(width,height)

 

Android RecyclerView利用Glide載入大量圖片into(Target)導致OOM異常

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.