Matisse 與 Glide -- java.lang.NoSuchMethodError: com.bumptech.glide.RequestManager.load

問題描述

  • 在使用 Matisseglide 4.0.0 以及 4.0.0 之后的版本過程中,發(fā)現通過
    Matisse 的 wiki 代碼調用選取圖片的方式后,會出現本文標題的錯誤
    1.以下為 wiki 調用代碼:
Matisse.from(MainActivity.this)
        .choose(MimeType.allOf())
        .countable(true)
        .maxSelectable(9)
        .addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K))
        .gridExpectedSize(getResources().getDimensionPixelSize(R.dimen.grid_expected_size))
        .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
        .thumbnailScale(0.85f)
        .imageEngine(new GlideEngine())
        .forResult(REQUEST_CODE_CHOOSE);

2.以下為控制臺報出的錯誤信息,內容過多,我就只截取了錯誤標題部分

java.lang.NoSuchMethodError: com.bumptech.glide.RequestManager.load
at com.zhihu.matisse.engine.impl.GlideEngine.loadThumbnail(GlideEngine.java:36)
at com.zhihu.matisse.internal.ui.widget.MediaGrid.setImage(MediaGrid.java:117)
at com.zhihu.matisse.internal.ui.widget.MediaGrid.bindMedia(MediaGrid.java:84)

問題定位

  • 通過報錯信息,可以發(fā)現出現錯誤的調用路徑,根據路徑依次查看,發(fā)現在類 GlideEngine.java中,出現如下代碼:
    @Override
    public void loadThumbnail(Context context, int resize, Drawable placeholder, ImageView imageView, Uri uri) {
        Glide.with(context)
                .load(uri)
                .asBitmap()  // some .jpeg files are actually gif
                .placeholder(placeholder)
                .override(resize, resize)
                .centerCrop()
                .into(imageView);
    }

其中,有一行顯示為紅色,也就是說,該行代碼出現錯誤,導致程序的崩潰。

.asBitmap()

問題分析

  • 在問題定位中,發(fā)現 Matisse 在通過 Glide 調用相關 api 的時候出現錯誤,因此,問題主要原因出現在 Glide 的使用上。通過查看 Glide 的 相關文檔,發(fā)現 Glide 從 v3 到 v4 做了一些改動。
  • 相關文檔 中發(fā)現
Glide.with(fragment)
    .asBitmap()
    .apply(myOptions)
    .load(url)
    .into(bitmapView);

仔細看這里的內容,這里 .asBitmap() 的調用是在 .load(url) 之前,而我們在 問題定位 中的代碼, .asBitmap() 的調用是在 .load(url) 之后。隨后我在測試中,調換了兩者的位置,發(fā)現 .asBitmap().load(url)之前調用沒有問題,而在 .load(url) 之后調用,的確出現了本文所描述的問題。

問題解決

  • 到此,問題的原因已經很明確了。下面來談談問題的解決方式。
  1. 簡單粗暴型的解決方式,將代碼中的.imageEngine(new GlideEngine()) 替換成 .imageEngine(new PicassoEngine())(注:需要 Picasso 依賴)
Matisse.from(MainActivity.this)
        .choose(MimeType.allOf())
        .countable(true)
        .maxSelectable(9)
        .addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K))
        .gridExpectedSize(getResources().getDimensionPixelSize(R.dimen.grid_expected_size))
        .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
        .thumbnailScale(0.85f)
      //.imageEngine(new GlideEngine())
        .imageEngine(new PicassoEngine())
        .forResult(REQUEST_CODE_CHOOSE);
  1. 自定義類MyGlideEngine,仿照類 GlideEngine,重新實現 ImageEngine,具體實現如下(注:該類未進行封裝,代碼不優(yōu)雅,各位可根據自己業(yè)務需求,進行相應的修改優(yōu)化)
public class MyGlideEngine implements ImageEngine {

    @Override
    public void loadThumbnail(Context context, int resize, Drawable placeholder, ImageView imageView, Uri uri) {
        RequestOptions options = new RequestOptions()
                .centerCrop()
                .placeholder(placeholder)//這里可自己添加占位圖
                .error(R.drawable.error)//這里可自己添加出錯圖
                .override(resize, resize);
        Glide.with(context)
                .asBitmap()  // some .jpeg files are actually gif
                .load(uri)
                .apply(options)
                .into(imageView);
    }

    @Override
    public void loadGifThumbnail(Context context, int resize, Drawable placeholder, ImageView imageView,
                                 Uri uri) {
        RequestOptions options = new RequestOptions()
                .centerCrop()
                .placeholder(placeholder)//這里可自己添加占位圖
                .error(R.drawable.error)//這里可自己添加出錯圖
                .override(resize, resize);
        Glide.with(context)
                .asBitmap()
                .load(uri)
                .apply(options)
                .into(imageView);
    }

    @Override
    public void loadImage(Context context, int resizeX, int resizeY, ImageView imageView, Uri uri) {
        RequestOptions options = new RequestOptions()
                .centerCrop()
                .override(resizeX, resizeY)
                .priority(Priority.HIGH);
        Glide.with(context)
                .load(uri)
                .apply(options)
                .into(imageView);
    }

    @Override
    public void loadGifImage(Context context, int resizeX, int resizeY, ImageView imageView, Uri uri) {
        RequestOptions options = new RequestOptions()
                .centerCrop()
                .override(resizeX, resizeY)
                .priority(Priority.HIGH);
        Glide.with(context)
                .asGif()
                .load(uri)
                .apply(options)
                .into(imageView);
    }

    @Override
    public boolean supportAnimatedGif() {
        return true;
    }

}

自定義類寫好后,將 .imageEngine(new GlideEngine()) 修改成 .imageEngine(new MyGlideEngine ()),然后運行項目,查看能否正常使用。

總結

  • 由于 Matisse 很久未更新維護,所以在 Glide 升級后,會出現這種問題。希望 Matisse 貢獻者在接下來的維護中,修復這個問題。
  • 本方案在我目前的項目中可正常使用,如果各位沒有解決問題,還請勿噴。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 一、簡介 在泰國舉行的谷歌開發(fā)者論壇上,谷歌為我們介紹了一個名叫Glide的圖片加載庫,作者是bumptech。這...
    天天大保建閱讀 7,786評論 2 28
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,351評論 25 708
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現,斷路器,智...
    卡卡羅2017閱讀 136,697評論 19 139
  • 上次青語組聚會,杜老師坐在我邊上。 大家起勁地說著,敬著酒?;丶也畔肫穑爬蠋熀苌僬f話。以前也是這樣,他幾乎不說話...
    行一館閱讀 260評論 0 0
  • 底層 從小火路 到古田 從古田 到歸元寺 還有許多許多次 從什么到什么 都是徒步 三寸金蓮的老太 是這樣的 赤腳趕...
    琴臺沙月閱讀 289評論 0 5

友情鏈接更多精彩內容