详解Matisse与Glide--java.lang.NoSuchMethodError:com.bumptech.glide.RequestManager.load

作者:bfther 时间:2021-06-21 02:09:19 

问题描述

在使用 Matisse 与 glide 4.0.0 以及 4.0.0 之后的版本过程中,发现通过
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)

问题定位

通过报错信息,可以发现出现错误的调用路径,根据路径依次查看,发现在类 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()

问题分析

在问题定位中,发现 Matisse 在通过 Glide 调用相关 api 的时候出现错误,因此,问题主要原因出现在 Glide 的使用上。通过查看 Glide 的 相关文档,发现 Glide 从 v3 到 v4 做了一些改动。
在 相关文档 中发现


Glide.with(fragment)
   .asBitmap()
   .apply(myOptions)
   .load(url)
   .into(bitmapView);

仔细看这里的内容,这里 .asBitmap() 的调用是在 .load(url) 之前,而我们在 问题定位 中的代码, .asBitmap() 的调用是在 .load(url) 之后。随后我在测试中,调换了两者的位置,发现 .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);

2.自定义类MyGlideEngine,仿照类 GlideEngine,重新实现 ImageEngine,具体实现如下(注:该类未进行封装,代码不优雅,各位可根据自己业务需求,进行相应的修改优化)


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 贡献者在接下来的维护中,修复这个问题。
本方案在我目前的项目中可正常使用,如果各位没有解决问题,还请勿喷。

来源:https://www.jianshu.com/p/220a7e5ce321

标签:Matisse,Glide,java,NoSuchMethodError,RequestManager
0
投稿

猜你喜欢

  • java爬取豆瓣电影示例解析

    2023-09-17 22:45:02
  • springboot整合EHCache的实践方案

    2023-08-23 23:48:31
  • Java中用爬虫进行解析的实例方法

    2021-06-23 09:07:00
  • C#怎样才能将XML文件导入SQL Server

    2022-02-16 17:51:13
  • Android开发之利用jsoup解析HTML页面的方法

    2023-03-31 19:03:03
  • JavaEE中struts2实现文件上传下载功能实例解析

    2023-03-09 07:54:31
  • MyBatis使用动态表或列代码解析

    2023-06-13 07:57:40
  • 教你使用Java获取当前时间戳的详细代码

    2021-09-19 04:41:02
  • C#中decimal保留2位有效小数的实现方法

    2023-01-30 07:35:13
  • C#的通用DbHelper类(支持数据连接池)示例详解

    2022-01-14 11:59:56
  • kotlin实现五子棋单机游戏

    2022-10-16 03:20:09
  • SpringBoot结合JWT登录权限控制的实现

    2023-10-06 04:54:22
  • 一文带你搞懂Java中方法重写与方法重载的区别

    2022-05-14 03:19:13
  • SpringBoot详解如何进行整合Druid数据源

    2022-05-10 10:46:54
  • Java多线程实现复制文件

    2023-03-21 07:54:17
  • Java 实战练手项目之校园超市管理系统的实现流程

    2023-07-09 08:46:55
  • Android 无障碍全局悬浮窗实现示例

    2023-07-30 08:50:01
  • 手把手教你JAVA进制之间的转换

    2023-11-14 23:18:56
  • Jenkins自动构建部署项目到远程服务器上的方法步骤

    2023-11-25 00:21:40
  • 一文详解Java拦截器与过滤器的使用

    2021-12-17 03:40:41
  • asp之家 软件编程 m.aspxhome.com