详解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


猜你喜欢
- 有一天,你写了好多好多带“形参”的构造函数(就是“方法”,同义),而且需要向这些构造函数里传递同样的“实参”,然后你就憨憨地一个一个函数的调
- 泛型概述我们都知道集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型。当我们在取出每一个对象,并且进
- 用Visual Studio等IDE写C#的Hello World非常简单,但脱离了IDE你能不能打印出Hello World呢?这不是说工
- 本文实例讲述了Android实现内存中数据保存到sdcard的方法。分享给大家供大家参考,具体如下:public static void w
- Web Fragment 是什么 - 它是在 servlet 3.0开始支持的,可以把一个dy web项目拆分为多个项目,解耦合,使其在项目
- 后端接收form-data创建实体类public class Para_list //实体类 { &n
- 本文实例为大家分享了Java控制台实现猜拳游戏的具体代码,供大家参考,具体内容如下1、目标通过控制台实现一个人机对战的猜拳游戏,用户通过输入
- 先上图下拉刷新跟原生开发一样,下拉刷新在flutter里提供的有组件实现 RefreshIndicator一直不明白为啥组件中都提供下拉刷新
- 最近安装了idea,觉得比eclipse好用很多,今天不知道为啥yml文件就不识别了,上面显示一个问号,我查了半天,解决办法就是安装一个插件
- 方法一:Hashtable ht = new Hashtable();  
- name和url属性的作用定义feign是声明式的web service客户端,它让微服务之间的调用变得更简单了,类似controller调
- 前言 短时间提升自己最快的手段就是背面试题,最近总结了Java常用的面试题,分享给大家,希望大家都能圆梦大厂,加油,我命由我不由天
- 目录位运算按位“与” &按位“或” |异或 ^移位运算左移 <<右移 >>无符号右移 >>>
- Lucene提供了一个简单却强大的应用程序接口(API),能够做全文索引和搜寻,在Java开发环境里Lucene是一个成熟的免费开放源代码工
- 本文实例为大家分享了Android调用外置摄像头的具体代码,供大家参考,具体内容如下1、布局文件<?xml version="
- 前言当你编写一个应用时,你通常都会希望用户能够定制化他们和应用交互的方式,以及应用与系统进行交互的方式。这种方式通常被称为 &ldq
- 一、C++11智能指针概述在C++中,动态内存的使用时有一定的风险的,因为它没有垃圾回收机制,很容易导致忘记释放内存的问题,具体体现在异常的
- Gituhb项目Volley源码中文注释项目我已经上传到github,欢迎大家fork和start.为什么写这篇博客本来文章是维护在gith
- java 打造阻塞式线程池的实例详解原来以为tiger已经自带了这种线程池,就是在任务数量超出时能够阻塞住投放任务的线程,主要想用在JMS消
- io学习框架:文件:保存数据的地方。1)常见文件对象的相关构造器和方法:当进行File file = new File(filePath);