kotlin - R8 混淆后接口中 Kotlin 泛型类型参数的问题
问题描述
无法弄清楚如何正确设置 R8 混淆规则以保持我的界面正常工作。
我正在发布一个库。它到处都有混淆代码,除了它是公共 API。
有一个基本接口BaseFoo
,在签名中有一个类型参数:
interface BaseFoo<D, E> {
fun handle(result: SomeOtherClass<D, E>): Boolean
}
然后有一个内部声明Bar
了派生接口的类DerivedFoo
:
class Bar {
interface DerivedFoo : BaseFoo<Alice, Bob>
}
使用 R8 使用混淆发布此代码后,尝试使用此库的接口DerivedFoo
失败:
val myDerivedFoo = object : Bar.DerivedFoo {
override fun handle(result: SomeOtherClass<Alice, Bob>): Boolean {
return false
}
}
object
这里显示错误:
对象不是抽象的,不实现抽象成员 public abstract fun handle(result: SomeOtherClass<Alice, Bob>): Boolean defined in com.example.Bar.DerivedFoo
该handle
方法分别给出了
'handle' 不覆盖任何内容
错误。如果您在此处使用自动完成功能创建一个覆盖函数,您将获得:
override fun handle(result: SomeOtherClass<D, E>): Boolean {
}
那就是 - 完全使用<D, E>
泛型参数(而不是<Alice, Bob>
),尽管编译器不知道那些D
和E
.
到目前为止,混淆配置设置了以下规则:
-keeppackagenames com.example.**
-keep public class com.example.Bar { *; }
-keep public interface com.example.Bar$DerivedFoo { *; }
# Common rules:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-dontshrink
-verbose
-ignorewarnings
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable,*Annotation*,Signature,InnerClasses,EnclosingMethod,MethodParameters,Exceptions
-keepparameternames
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!code/allocation/variable
任何人都可以阐明如何处理这个丢失的派生接口签名吗?
更新:可以在此处找到具有重现问题的示例
解决方案
看来配置是正确的,一切都应该工作。但我猜这不是因为一些 Kotlin 互操作性问题。
好消息是,与其他与 Kotlin 相关的问题一起,这已在 2.1.42 版本中得到修复。
所以给定问题的解决方案是强制使用相应的 R8 版本:
buildscript {
repositories {
maven {
url 'https://storage.googleapis.com/r8-releases/raw'
}
}
dependencies {
classpath 'com.android.tools:r8:2.1.42' // Must be before the Gradle Plugin for Android.
classpath 'com.android.tools.build:gradle:X.Y.Z' // Your current AGP version.
}
}
学分转到这个答案
推荐阅读
- java - 在 actionperformed 中创建 JDialog
- mongodb - Next.js + Apollo + Mongodb:在 SSR 模式下无法访问 Apollo 上下文
- kubernetes - 在 Kubernetes 上安装 awx-operator 时出现 AWX-Web 错误
- c - 如何将数组从 PLC 程序传递到 TwinCAT 中的 C 模块实例?
- raspberry-pi3 - 无法将裸 Menment Raspberry 二进制文件启动到 0x80000
- javascript - 远程连接的 WebSocket 问题
- reactjs - 一次 ReactJS 列出对象列表中的项目
- javascript - Fetch 被触发两次
- javascript - 我可以在反应中使用人脸识别 npm 包吗?
- c++ - 如何使用 emscripten embind 将 json 对象作为参数传递给 c++ 函数