Избегайте использования виртуального метода registerAnimationCallback с минимизацией Glide и Proguard - PullRequest
0 голосов
/ 23 апреля 2019

У нас есть пользовательская библиотека (com.example.mylib), включаемая нашим приложением в качестве внешней зависимости (com.example.myapp). Наша библиотека, в свою очередь, использует библиотеку Glide GIF . Кроме того, наша библиотека минимизируется Proguard.

Во время выполнения наше приложение падает со следующим logcat:

2019-04-23 15:47:46.642 11066-11066/com.example.myapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myapp, PID: 11066
    java.lang.NoSuchMethodError: No virtual method registerAnimationCallback(Landroid/support/graphics/drawable/Animatable2Compat$AnimationCallback;)V in class Lcom/bumptech/glide/load/resource/gif/GifDrawable; or its super classes (declaration of 'com.bumptech.glide.load.resource.gif.GifDrawable' appears in /data/app/com.example.myapp-C3jnO5_79zyarj8XR40khQ==/split_lib_dependencies_apk.apk)
        at com.example.mylib.MyComponent$1.onResourceReady(SourceFile:4)
        at com.example.mylib.MyComponent$1.onResourceReady(SourceFile:1)
        at com.bumptech.glide.request.SingleRequest.onResourceReady(SingleRequest.java:574)
        at com.bumptech.glide.request.SingleRequest.onResourceReady(SingleRequest.java:549)
        at com.bumptech.glide.load.engine.EngineJob.handleResultOnMainThread(EngineJob.java:218)
        at com.bumptech.glide.load.engine.EngineJob$MainThreadCallback.handleMessage(EngineJob.java:324)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Я не могу понять, почему метод GifDrawable.registerAnimationCallback(...) запутан.

Я думаю, что мы следовали всем предложенным правилам Proguard / Glide:

  • Расширение пользовательского класса LibraryGlideModule
  • построить зависимости, такие как com.github.bumptech.glide:glide:4.9.0, com.github.bumptech.glide:compiler:4.9.0, com.zlc.glide:webpdecoder:0.0.8.4.7.1
  • Правила Proguard для Glide, скопированные из Официальный файл readme

Я вижу автоматически сгенерированные Glide-файлы в каталоге build\. Кроме того, проверяя сгенерированный файл JAR под packaged-classes\, я не вижу ничего подозрительного: только наши пользовательские общедоступные компоненты хранятся в открытом виде, другие пользовательские частные / анонимные / и т.д. компоненты минимизированы.

Даже если это не имеет большого смысла при создании нашей библиотеки, я также оставил без изменений следующее, не повезло:

# our custom, anonymous RequestListeners
-keep class * implements com.bumptech.glide.request.RequestListener {
    public *;
}

# GifDrawable itself by Glide
-keep class com.bumptech.glide.load.resource.gif.GifDrawable {
    public *;
}

Для тех, кто не привык к Glide или интересуется, что интересного в коде, вот оно:

Glide.with(myContext)
    .asGif()
    .load(myResourceId)
    .listener(new RequestListener<GifDrawable>() {

        @Override
        public boolean onResourceReady(GifDrawable resource,
                                       Object model,
                                       Target<GifDrawable> target,
                                       DataSource dataSource,
                                       boolean isFirstResource) {
            myReadyGif = resource;
            resource.setLoopCount(1);
            resource.registerAnimationCallback(
                new Animatable2Compat.AnimationCallback() {
                    @Override
                    public void onAnimationEnd(Drawable drawable) {
                        super.onAnimationEnd(drawable);
                        // do something
                    }
                });
            return false;
        }

        //...
    })
    .into(myViewTarget);

Будучи registerAnimationCallback относительно новым дополнением к библиотеке Glide, мне интересно, связана ли эта проблема с самой библиотекой. Пока не уверен, что это значит, но предыдущий setLoopCount(...) вызов метода не вызывает проблем.

1 Ответ

0 голосов
/ 23 апреля 2019

Хорошо, это была полная ошибка копирования / вставки от нас детализации , когда мы извлекали код и конфигурацию из приложения для создания выделенного модуля библиотеки:

во время сборки приложения.gradle включает в себя зависимость Glide как:

implementation 'com.github.bumptech.glide:glide:4.9.0'

, когда то же самое переносится в библиотеку, его следует включить в:

api 'com.github.bumptech.glide:glide:4.9.0'

Противоречие было с копией /Ошибка вставки по-прежнему на месте, этого было достаточно для повторного добавления зависимости в приложение, и ошибка времени выполнения исчезла.

...