You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止ProGuard修改Android库中Kotlin suspend函数签名?

解决Kotlin Suspend方法在ProGuard处理后签名失效的问题

问题背景

为Android库编写了包含suspend方法的Kotlin接口作为Facade:

interface Facade {
    suspend fun doSomeWork(): String
}

添加ProGuard规则尝试保留该接口:

-keep interface com.some.library.Facade { *; }

但接入应用后无法以suspend函数方式调用doSomeWork,反编译发现方法签名被修改为:

public interface Facade {
    @Nullable
    Object doSomeWork(@NotNull Continuation<? super String> var1);
}

禁用ProGuard则一切正常。

已尝试的无效方案

  • 添加-keepattributes Signature,LineNumberTable,RuntimeVisibleAnnotations,AnnotationDefault,Code
  • 保留整个包-keep com.some.library.** { *; }
  • 保留Kotlin相关类-keep class kotlin.** { *; }和-keep class kotlinx.** { *; }
  • 替换ProGuard配置文件为proguard-android.txt
  • 禁用R8 full模式android.enableR8.fullMode=false

正确解决方案

调整ProGuard规则

需要同时保留接口方法的完整签名,以及Kotlin识别suspend方法所需的元数据属性:

# 保留Facade接口及其所有方法的完整签名(包括泛型参数)
-keep interface com.some.library.Facade {
    <methods>;
}

# 保留关键属性,确保Kotlin能解析suspend方法的元数据
-keepattributes Signature, RuntimeVisibleParameterAnnotations, RuntimeVisibleAnnotations

规则解释

  1. <methods> 相较于 * 更明确地保留方法的完整签名,包括参数的泛型信息——suspend函数的返回类型依赖于Continuation<? super String>中的泛型参数,这是Kotlin识别suspend方法的核心。
  2. Signature 属性用于保留泛型类型信息,缺失后Kotlin无法关联字节码方法与原suspend函数的返回值类型。
  3. RuntimeVisibleParameterAnnotations 和 RuntimeVisibleAnnotations 保留参数和方法的注解(比如@NotNull),这些注解是Kotlin编译器验证suspend方法签名的必要信息。

补充说明

如果使用R8(AGP默认的混淆工具),确保没有额外开启会移除泛型或注解的优化规则。上述规则已经覆盖了R8和ProGuard的核心需求,无需单独保留整个Kotlin类库。

内容的提问来源于stack exchange,提问作者Roman Svyatnenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 01:45:18