在用 Kotlin 编写的 Android 库的公共 API 中处理 R8 + JvmStatic Annotation + Lambda

2024-04-20

首先请注意,我并不期待why do you want to obfuscate library评论。这是我要问的一个真正的问题。

我在使用 Kotlin 编写的 Android 库处理 R8/混淆时遇到了问题。

我有一个公共 API 方法,其注释为@JvmStatic该方法需要一个Lambda作为参数。

例如,看一下下面的代码,

typealias MyLambdaCallback = (String, Map<String, Any>) -> Unit

@Keep
object MyApi {

    private var callback: MyLambdaCallback? = null

    @JvmStatic
    fun setCallback(callback: MyLambdaCallback) {
        this.callback = callback
    }
}

我已经添加了@Jvmstatic以便Java调用代码可以静态调用方法而不是执行MyApi.INSTANCE.setCallback()

当我释放库时没有minification,一切都很好,并且从两者调用代码Java and Kotlin已按预期写入。

但现在我想在打开时释放库minification.

这就产生了一个问题。

这是错误

java.lang.InknownClassChangeError:方法“void setCallback(kotlin.jvm.functions.Function2)”预计为 virtual 类型,但发现为 static 类型(出现“com.demo.basic.Application”声明)在/data/app/com.demo.basic-_0uJXPbtfs3UZ2Rp2h-RdQ==/base.apk!classes2.dex)

我是否在某个地方犯了错误,或者这被认为是某种限制?

我尝试了什么?

  1. 去除@Jvmstatic解决了问题,但它创建了丑陋的 Java 调用代码

  2. Kept @Jvmstatic但删除了Lambda将 Lambda 转换为interface with one method一切正常。很遗憾SAM for Kotlin classes还没到,所以打电话Kotlin代码看起来很难看。


这是在 R8 问题跟踪器上跟踪的http://issuetracker.google.com/158393309 http://issuetracker.google.com/158393309其中有更多详细信息。

简而言之,这个问题已在 R8 2.1.35 版本中修复,可以通过对顶层进行以下更改来使用build.gradle file:

repositories {
    maven {
        url 'https://storage.googleapis.com/r8-releases/raw'
    }
}

dependencies {
    classpath 'com.android.tools:r8:2.1.35'          // Must be before the Gradle Plugin for Android.
    classpath 'com.android.tools.build:gradle:X.Y.Z' // Your current AGP version.
 }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在用 Kotlin 编写的 Android 库的公共 API 中处理 R8 + JvmStatic Annotation + Lambda 的相关文章

随机推荐

  • 不变违规:requireNativeComponent:在 UIManager 中找不到“RCTView”

    当我从开发菜单启动远程 js 调试并在 Android 模拟器中重新加载我的 React Native 应用程序时 会出现此错误 Invariant Violation requireNativeComponent RCTView was
  • IE7 与我的 jQuery 相关的问题 [点击并更改功能]

    我有以下代码片段 基本上我想做的是在第一次单击函数中循环遍历缓存的 JSON 数据并显示该 id 存在的任何值 在第二个更改函数中 每当其中一个元素更改值时 即从是到否 反之亦然 我都会捕获 这些元素都是通过我从 Web 服务接收到的 JS
  • 在 C# 中创建值列表的快速方法?

    我正在寻找一种在 C 中创建值列表的快速方法 在 Java 中 我经常使用下面的代码片段 List
  • 从控制台应用程序同步击键读取

    我想立即读取 Windows 和 Linux 下用 C 编写的控制台应用程序中的每一次击键 不幸的是 当按下 输入 返回 键时 函数 gets line 只返回一个值 我正在寻找一个在按下按键后立即返回的函数 目前我的代码看起来像这样 ch
  • 如何使用 Intel 语法内联汇编在 GCC 中设置变量?

    为什么这个代码没有设置temp到 1 我实际上该如何做到这一点 int temp asm intel syntax mov 0 eax mov eax 1 att syntax r 1 r temp eax printf d n temp
  • 对 xhtml5 感到困惑:不再有“”,现在强制使用“meta”?

    我已经是长期用户XHTML 1 0 Strict 我现在正尝试在我的新项目中切换到 XHTML5 我很困惑对于 HTML5 不再被认为是有效的http validator w3 org http validator w3 org 这是为什么
  • 我无法更新 Google App 脚本上的脚本

    我在公司使用Google App 更新脚本时经常遇到问题 当我更新我的脚本时 我在 Google 网站上的网页没有更新 而且很长一段时间 更新脚本时我必须创建一个新脚本 我可以解决这个问题吗 regards 有两种方法可以publish你的
  • 如何更轻松地在 Emacs 中的缓冲区之间切换?

    我最近开始使用 emacs 并且大部分时间我都很享受使用它 我唯一不喜欢的是在缓冲区之间切换 我经常打开一些缓冲区 并且我已经厌倦了使用C x b and C x C b 是否有任何软件包可以使缓冲区之间的切换变得更容易 我调查过emacs
  • 测试应用程序的可访问性(对讲)

    我正在使我的应用程序可访问性兼容 为此 通过在 xml 中提供 android contentDescription your string 来向可访问性框架提供正确的数据 我还看到了关于使应用程序可访问的 Android 开发人员指南 概
  • 沟通差距:用户与分析师-设计师

    通常的做法是使用案例研究 构建工作流和数据流等 但这并不一定会在用户 发起者和分析师 设计者之间创建共享词汇表 通常 其中一方都必须获得其他专业领域 内部 的术语和观点 这通常会导致误解和澄清会议 进入 RAD 技术 如进化原型 等 用户
  • 在Java中声明布尔变量的正确方法是什么?

    我刚刚开始学习Java 在我关注的在线课程中 我被要求尝试以下代码 String email1 email protected cdn cgi l email protection String email2 email protected
  • Sklearn LogisticRegressionCV 的类似数组的输入

    最初 我从a读取数据 csv文件 但在这里我从列表构建数据框 以便可以重现问题 目的是使用交叉验证来训练逻辑回归模型LogisticRegressionCV indeps M F M F M M F M M F F F F F M F F
  • 使用 Numpy for Python 创建 cx_Freeze exe

    我正在尝试使用 cx Freeze 创建一个基本的 exe 它适用于没有 numpy 的 py 程序 但我无法使用 numpy 正确制作一个程序 有想法该怎么解决这个吗 我需要在 setup py 中包含一些内容吗 当我去运行 exe 时
  • 更改传单归属控制位置

    我在我的应用程序中使用 WebView 来显示传单地图 在 HTML 文件中 我有以下制作人员和链接 L tileLayer https api tiles mapbox com v4 id z x y png access token x
  • 使用 LLVM 为整个源代码生成 CFG

    LLVM 社区的任何人都知道是否有一种方法可以使用以下方法为整个输入源代码生成 CFG opt dot cfg foo ll bc 由于此函数为每个函数生成 CFG 因此函数之间的连接将被忽略 看来旧的分析工具已经贬值了 我想知道你是否找到
  • 使用 highcharts 在堆栈标签中显示特定系列值

    这是我正在处理的内容 http jsfiddle net josip0423 prJjY 171 http jsfiddle net josip0423 prJjY 171 过去几个小时我一直在努力解决这个问题 但一无所获 我对 javas
  • C# 异步操作

    实际上我很难理解 BeginInvoke 和 EndInvoke 对 class AsynchronousDemo public delegate void DemoDelegate static void Main DemoDelegat
  • glGenerateMipmap 是否在 sRGB 纹理的线性空间中执行平均?

    OpenGL 3 3 规范似乎没有要求 mipmap 生成在线性空间中完成 我能找到的只有以下内容 派生的 mipmap 数组的内部格式都与 levelbase 数组和派生数组的维度如下 第 3 8 14 节中描述的要求 的内容 派生数组是
  • GPS 坐标(以度为单位)来计算距离

    在iPhone上 我以十进制度数获取用户的位置 例如 纬度39 470920和经度 0 373192 也就是A点 我需要用另一个 GPS 坐标 同样以十进制表示 B 点创建一条线 然后 计算从 A 到 B 的线与另一个点 C 之间的距离 垂
  • 在用 Kotlin 编写的 Android 库的公共 API 中处理 R8 + JvmStatic Annotation + Lambda

    首先请注意 我并不期待why do you want to obfuscate library评论 这是我要问的一个真正的问题 我在使用 Kotlin 编写的 Android 库处理 R8 混淆时遇到了问题 我有一个公共 API 方法 其注