我们的应用程序(com.example.myapp)将自定义库(com.example.mylib)作为外部依赖项包含在内。我们的图书馆又使用Glide GIF handling库。此外,我们的图书馆由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
我可以在build\
目录下看到自动生成的Glide文件。另外,在packaged-classes\
下检查生成的JAR文件,我看不到任何可疑的东西:只有我们的自定义公共组件保持清晰,其他自定义私有/匿名/等。组件缩小。
即使它在建立我们的图书馆时不应该有很大的意义,我也一直没有通知以下,没有运气:
# 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(...)
方法调用没有引起任何问题。
好的,当我们从应用程序中提取代码和配置以创建专用库模块时,这是我们对细节的完全复制/粘贴错误:
app build.gradle包含Glide依赖关系:
implementation 'com.github.bumptech.glide:glide:4.9.0'
当相同的移植到库时,它应该转向:
api 'com.github.bumptech.glide:glide:4.9.0'
反证据是,在复制/粘贴错误仍然存在的情况下,也足以将依赖项重新添加到应用程序,并且运行时错误消失了。