Detailed explanation of Matisse and Glide java. lang. NoSuchMethodError: com. bumptech. glide. RequestManager. load

  • 2021-12-13 16:53:01
  • OfStack

Problem description

In the process of using Matisse and glide 4.0. 0 and after 4.0. 0, it was found that the
When the wiki code of Matisse calls the way to select pictures, an error will appear in the title of this article
1. The following is the wiki call code:


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. The following is the error message reported by the console. There are too many contents, so I only intercepted the error header part


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)

Problem orientation

By reporting error information, you can find the call path with error. According to the path, you can find the following code in the class 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);
    }

Among them, one line is displayed in red, that is to say, there is an error in the code of this line, which leads to the crash of the program.


.asBitmap()

Problem analysis

In the problem location, it is found that Matisse has an error when calling related api through Glide, so the main cause of the problem lies in the use of Glide. By looking at the relevant documentation of Glide, it is found that Glide has made some changes from v3 to v4.
Found in related documents


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

Look closely here, where the call to. asBitmap () comes before. load (url), and our code in problem location, the call to. asBitmap () comes after. load (url). Then in my tests, I switched the positions of both and found that. asBitmap () had no problem calling before. load (url), while calling after. load (url) did have the problems described in this article.

Problem solving

By this point, the cause of the problem has been made clear. Let's talk about the solution to the problem.

1. A simple and crude solution, replacing. imageEngine (new GlideEngine ()) in the code with. imageEngine (new PicassoEngine ()) (Note: Picasso dependency is required)


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. Customize the class MyGlideEngine, imitate the class GlideEngine, and re-implement ImageEngine. The specific implementation is as follows (Note: This class is not encapsulated, and the code is not elegant. You can modify and optimize it according to your own business needs)


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)// You can add your own placeholder here 
                .error(R.drawable.error)// You can add your own error diagram here 
                .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)// You can add your own placeholder here 
                .error(R.drawable.error)// You can add your own error diagram here 
                .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;
    }

}

After the custom class is written, change. imageEngine (new GlideEngine ()) to. imageEngine (new MyGlideEngine ()), and then run the project to see if it works properly.

Summarize

Since Matisse has not been updated and maintained for a long time, this problem occurs after Glide is upgraded. I hope Matisse contributors will fix this problem in the next maintenance.
This program can be used normally in my current project. If you don't solve the problem, please don't spray it.


Related articles: