Thanks to all those who participated in our inaugural ProGuard Playground Challenge! We were thrilled to see more people leverage the rule visualizer and many who even completed all 5 challenges. A reminder, although the contest is over, you can still try the challenges at any time here.
Question 1:
How would you write a keep rule for the onCreate method in com.example.HelloWorldActivity?
Answer:
For our first challenge we were looking for -keep or -keepclassmembers. A few only allowed shrinking but for this exercise we wanted to see all features used including shrinking, optimization, and obfuscation.
-keep class com.example.HelloWorldActivity {
public void onCreate(android.os.Bundle);
}
Question 2:
How do you keep a constant field in a Kotlin companion object?
Write a keep rule to keep the CONSTANT field from the following Kotlin code:
package companion
class Foo {
companion object {
const val CONSTANT = "bar"
fun foo() = println("foo")
}
}
Answer:
Although there are several approaches to this challenge we were looking for some version of -keep class or -keepclassmembers class:
-keep class companion.Foo {
public static final java.lang.String CONSTANT;
}
Question 3:
You see the following exception when running your application after applying ProGuard/R8/DexGuard because you are accessing a field through reflection:
java.lang.NoSuchFieldException: No field userId in class Lcom/example/HelloWorldActivity;
Write a keep rule that allows accessing this field through reflection
Answer:
Here we were looking for a rule that keeps the field using either -keep or -keepclassmembers
-keep class com.example.HelloWorldActivity {
public java.lang.String userId;
}
Question 4:
You are building a library SDK, you want to shrink & optimize the SDK except for the public API
Your SDK API consists of all the public & protected members and public classes, except for those in the com.example.mylibrary.internal package.*
Write a keep rule which allows shrinking, optimization & name obfuscating the SDK except for the public API.
Answer:
-keep public class !com.example.mylibrary.internal.** {
public protected *;
}
It’s worth remembering that some did not keep all the classes such as protected member. Additionally, using “*” vs. “**” can also lead to an incorrect output.
Question 5:
How do you conditionally keep entities, based on the existence of others?
Write a conditional keep rule, that keeps all the *members* of a class if there exists a class with the same name but with the _Adapter suffix. The _Adapter classes themselves should *not be kept*.
For example, if class A_Adapter exists then the members in class A should be kept. But neither class A nor class A_Adapter should not be kept.
Hint: check out the manual section about “-if” and “-keepclassmembers”
ProGuard Manual: Usage | Guardsquare
ProGuard Manual: Usage | Guardsquare
Answer:
-if class **_Adapter
-keepclassmembers class <1>{
*;
}
Finally, the moment you’ve all been waiting for. The winners are….
- For a $100 credit towards Udemy courses - @Thiago_Horai & @rennanpossas!
- And the winners of a Guardsquare swag pack - @Sp4ghettiCode, @faleksicdev, @gobruins07, @hibob224, @caroltr, @peret, @otavio.ses, @Creepseep,@JerneV, @SirionRazzer
For the winners, we will be in touch soon to coordinate your rewards.
Thank you to everyone that participated in this initiative and looking forward to doing this again!