简体   繁体   中英

Kotlin, Proguard and lambdas

I have a neat function that does something on a view:

fun<T : View> Activity.withView(nr : Int, fn : T.()->Unit) {
    (findViewById(nr) as T?)?.fn()
}

Now, when I use this function in my activity:

    withView<Spinner>(R.id.spinner_toolbar) {
        adapter = AdapterIndeksuDlaSpinnera(this@NewMainActivity, PlaylistIndex)

...everything is OK until I use ProGuard. I can see AdapterIndeksuDlaSpinnera gets mangled, as expected, but the application fails when proguarded with "Can't load class AdapterIndeksuDlaSpinnera" (while it should complain about mangled adapter name).

I was able to create temporaty workaround by disabling mangling of all adapters that can be used inside my withView

-keep class pl.qus.xenoamp.adapter.** { *; }

but I don't feel it's a good solution (and I have no idea what other classes can fail this way!). So can anyone explain what is the problem and what ProGuard line should I add to potentially fix similar occurences of other classes used inside withView ?

This is a tough one. In nutshell, Proguard does not know about Kotlin. It is using a simple code analysis to detect things like Class.forName() and work around them, but may fail for anything more complex. You need to look at generated .class files from build subdirectories (can you post relevant ones?) to find out what really happens.

For now you can do two things:

  • Ask Kotlin devs to add proper obfuscation/optimization support to the Kotlin compiler: this is really the right way to do things, as demonstrated by every non-java compiler in existence;
  • Exclude your own sources from obfuscation (most Activities and Views aren't going to be well-obfuscated anyway).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM