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

如何在不使用-keep规则的情况下防止未使用Fragment被ProGuard删除?

解决方案

首先明确:ProGuard会移除它判定为“未被使用”的类,而反射调用的字符串引用不会被它识别为有效引用,所以FragmentName会被移除。-keepnames只保留类名但不会阻止类被移除,所以确实无效。以下是不用宽泛-keep规则(或完全不用ProGuard规则)的可行方案:

方案1:使用精确的-keep规则(推荐)

团队觉得-keep宽泛是因为可能用了-keep class com.bla.bla.**这类包级规则,但你可以针对单个Fragment写精确规则,完全不存在宽泛问题:

# 仅保留指定Fragment类及其无参构造方法(反射需要)
-keep class com.bla.bla.FragmentName {
    public <init>();
}

这个规则只作用于FragmentName一个类,不会影响其他类的混淆和移除,完全符合“不宽泛”的要求,是最规范的解决方式。

方案2:添加代码假引用(无需修改ProGuard规则)

在某个肯定不会被ProGuard移除的类(比如你的Application子类)中添加一段不会实际执行的代码,让ProGuard认为FragmentName被引用了:

class MyApplication : Application() {
    // 仅用于欺骗ProGuard,不会被执行
    @Suppress("UNUSED")
    private fun dummyReference() {
        if (false) {
            FragmentName()
        }
    }
}

由于if(false)的存在,这段代码会被ProGuard的优化阶段移除,不会影响运行性能,但ProGuard在分析引用关系时会认为FragmentName被使用,从而不会删除该类。缺点是需要维护这段冗余代码。

方案3:使用@Keep注解(代码层面标记)

AndroidX提供了@Keep注解,添加在Fragment类上可以让ProGuard自动保留该类:

import androidx.annotation.Keep

@Keep
class FragmentName : Fragment() {
    // 类实现
}

这个注解本质是在编译时生成精确的-keep规则,和方案1效果一致,但更直观,代码可读性更高,不需要手动编写ProGuard规则。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 18:10:48