避免使用Glide和Proguard缩小的虚拟方法registerAnimationCallback

问题描述 投票:0回答:1

我们的应用程序(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.0com.github.bumptech.glide:compiler:4.9.0com.zlc.glide:webpdecoder:0.0.8.4.7.1
  • official readme复制的特定于Glide的Proguard规则

我可以在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(...)方法调用没有引起任何问题。

android proguard android-glide android-proguard
1个回答
0
投票

好的,当我们从应用程序中提取代码和配置以创建专用库模块时,这是我们对细节的完全复制/粘贴错误:

app build.gradle包含Glide依赖关系:

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

当相同的移植到库时,它应该转向:

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

反证据是,在复制/粘贴错误仍然存​​在的情况下,也足以将依赖项重新添加到应用程序,并且运行时错误消失了。

© www.soinside.com 2019 - 2024. All rights reserved.