为什么在proguard输出的usage.txt中仍显示一个用过的功能?

发布于 2025-01-27 18:47:06 字数 1787 浏览 2 评论 0原文

我有以下代码

class MainActivity : AppCompatActivity() {
    private val obfuscatedClass = MyObfuscatedClass()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        obfuscatedClass.usedFunc()
    }
}

class MyObfuscatedClass {
    fun usedFunc() {}
    fun unusedFunc() {}
}

具有正常的proguard,我会生成ustage.txt文件,显示unusterfunc()

com.example.myobfuscateretracetest.MyObfuscatedClass:
    public final void unusedFunc()

这是正确的,因为usage.txt文件旨在显示类或删除函数在编译期间,如

但是,如果我将我的类更改为懒惰,如下所示,

class MainActivity : AppCompatActivity() {
    private val obfuscatedClass by lazy {
        MyObfuscatedClass()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        obfuscatedClass.usedFunc()
    }
}

class MyObfuscatedClass {
    fun usedFunc() {}
    fun unusedFunc() {}
}

当我检查usage.txt时,我注意到这两个都在不同的部分中显示

com.example.myobfuscateretracetest.MyObfuscatedClass:
    public final void unusedFunc()

// ... other sections

com.example.myobfuscateretracetest.MyObfuscatedClass:
    public final void usedFunc()

为什么underfunc()仍在usage.txt中显示?

I have the following code

class MainActivity : AppCompatActivity() {
    private val obfuscatedClass = MyObfuscatedClass()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        obfuscatedClass.usedFunc()
    }
}

class MyObfuscatedClass {
    fun usedFunc() {}
    fun unusedFunc() {}
}

With a normal proguard, I generate the usage.txt file, showing the unusedFunc() there

com.example.myobfuscateretracetest.MyObfuscatedClass:
    public final void unusedFunc()

This is correct, as the usage.txt file is meant to show the class or removed function during compilation as mentioned in

However, if I change my class to a lazy as shown below,

class MainActivity : AppCompatActivity() {
    private val obfuscatedClass by lazy {
        MyObfuscatedClass()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        obfuscatedClass.usedFunc()
    }
}

class MyObfuscatedClass {
    fun usedFunc() {}
    fun unusedFunc() {}
}

When I check the usage.txt, I notice that both also shown, just in a different section

com.example.myobfuscateretracetest.MyObfuscatedClass:
    public final void unusedFunc()

// ... other sections

com.example.myobfuscateretracetest.MyObfuscatedClass:
    public final void usedFunc()

Why is the usedFunc() still being shown in the usage.txt?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

就像说晚安 2025-02-03 18:47:06

显然,上述方案2的奇怪行为仅在使用

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

非优化默认proguard时才发生,然后没关系。

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

尽管使用该功能,但优化的Proguard可以更高级优化,但是它仍然被优化了吗?

Apparently the odd behavior of scenario 2 above only happen when using

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

If I use the non-optimize default proguard, then it's alright.

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

Perhaps the optimize proguard does more advanced optimization, though the function is used, but it still got optimized away?

变身佩奇 2025-02-03 18:47:06

可能与此有关:

Java编译器嵌入式原始常数和字符串常数(静态最终字段)。因此,proguard将列出该字段,即即使在源文件中使用的类文件中未使用的字段。我们可以添加 - keepClassMembers选项,以使这些字段保持优先级,以避免列出它们:

-keepclassmembers class * {
    static final %                *;
    static final java.lang.String *;
}

尝试将其添加到您的proguard.pro文件中并再次运行它,应停止打印这些静态成员的用法我们可以看到)

Probably related to this:

The java compiler inlines primitive constants and String constants (static final fields). ProGuard would therefore list such fields as not being used in the class files that it analyzes, even if they are used in the source files. We can add a -keepclassmembers option that keeps those fields a priori, in order to avoid having them listed:

-keepclassmembers class * {
    static final %                *;
    static final java.lang.String *;
}

Try adding that to your proguard.pro file and run it again should stop printing out usages of those static members (which are stripped but not that we can see)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文