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

Android升级Gradle7.x后Class.getInterfaces()返回空数组求助

问题场景与解决方案

问题复现代码

Java代码

// ITest.java
interface ITest {

}

// TestA.java
class TestA implements ITest {

}

// TestB.java
class TestB extends TestA implements ITest {

}

// main function
void main() {
    TestB testB = new TestB();
    Class[] interfaces = testB.getClass().getInterfaces();
    // Gradle7.x开启minifyEnabled=true时,count为0
    int count = interfaces.length;
}

Build配置

// build.gradle
android {
   buildTypes {
      debug {
        minifyEnabled true
      }
  }
}

问题原因

Gradle7.x搭配的Android Gradle Plugin7.x默认使用的R8混淆器会做冗余接口实现移除优化:TestB继承的TestA已经实现了ITest,R8判定TestB显式声明implements ITest属于冗余代码,编译时会移除这个声明,导致反射调用getInterfaces()拿不到ITest接口。而Gradle6.x用的旧版混淆工具没有这个优化,所以能正常返回长度1。

解决方案

方案1:添加R8规则保留接口声明

在项目的proguard-rules.pro(或r8-rules.pro)里加下面的规则,替换成实际包名:

-keep class 你的包名.TestB implements 你的包名.ITest

这条规则告诉R8不要移除TestB对ITest的显式实现声明,反射就能正常获取到接口。

方案2:修改代码逻辑遍历父类接口

不想依赖混淆规则的话,改反射逻辑,递归遍历当前类和所有父类的接口,确保收集到所有实现的接口:

void main() {
    TestB testB = new TestB();
    Set<Class<?>> allInterfaces = new HashSet<>();
    Class<?> currentClass = testB.getClass();
    
    // 遍历当前类及父类,收集所有接口
    while (currentClass != null) {
        Collections.addAll(allInterfaces, currentClass.getInterfaces());
        currentClass = currentClass.getSuperclass();
    }
    
    // 此时allInterfaces.size()为1,包含ITest
    int count = allInterfaces.size();
}

这种方式不依赖混淆配置,兼容性更强,后续R8规则变化也不受影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 20:43:12