Search code examples
androidproguardandroid-r8

Why is an in used function still shown in usage.txt of proguard output?


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?


Solution

  • 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?