У нас есть пользовательская библиотека (com.example.mylib), которая включается в качестве внешней зависимости нашим приложением (com.example.myapp). Наша библиотека, в свою очередь, использует библиотеку Glide для обработки GIF. Кроме того, наша библиотека минимизирована Proguard.
Во время выполнения наше приложение вылетает со следующим логарифмом:
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(...)
не вызывает проблем.