Entry points

  • In the shrinking step, ProGuard starts from these seeds and recursively determines which classes and class members are used. All other classes and class members are discarded.
  • In the optimization step, ProGuard further optimizes the code. Among other optimizations, classes and methods that are not entry points can be made private, static, or final, unused parameters can be removed, and some methods may be inlined.
  • In the obfuscation step, ProGuard renames classes and class members that are not entry points. In this entire process, keeping the entry points ensures that they can still be accessed by their original names.
  • The preverification step is the only step that doesn’t have to know the entry points.
Shirink를 통해 사용하지 않는 class들과 class member들을 삭제하고, Optimize를 통해 코드를 좀더 최적화하며, Obfuscate를 통해 난독화 합니다.
Android의 경우, proguard-android-optimize.txt를 사용해야 Optimize 과정이 수행됩니다.

Keep options

-keep [,modifier,...] class_specification

Specifies classes and class members (fields and methods) to be preserved as entry points to your code. For example, in order to keep an application, you can specify the main class along with its main method. In order to process a library, you should specify all publicly accessible elements.

-keepclassmembers [,modifier,...] class_specification

Specifies class members to be preserved, if their classes are preserved as well. For example, you may want to keep all serialization fields and methods of classes that implement theSerializable interface.

-keepclasseswithmembers [,modifier,...] class_specification

Specifies classes and class members to be preserved, on the condition that all of the specified class members are present. For example, you may want tokeep all applications that have a main method, without having to list them explicitly.

# preserve all public classes extending android.app.Activity.
-keep public class * extends android.app.Activity
# preserve all static class members named CREATOR on the condition if they are implementing android.os.Parcelable.
-keepclassmembers class * implements android.os.Parcelable {
static ** CREATOR;
}
# preserve all classes if they have below constructors.
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepnames class_specification

Short for -keep,allowshrinkingclass_specification. Specifies classes and class members whose names are to be preserved, if they aren't removed in the shrinking phase. For example, you may want to keep all class names of classes that implement theSerializable interface, so that the processed code remains compatible with any originally serialized classes. Classes that aren't used at all can still be removed. Only applicable when obfuscating.

-keepclassmembernames class_specification

Short for-keepclassmembers,allowshrinkingclass_specification. Specifies class members whose names are to be preserved, if they aren't removed in the shrinking phase. For example, you may want to preserve the name of the synthetic class$methods when processing a library compiled by JDK 1.2 or older, so obfuscators can detect it again when processing an application that uses the processed library (although ProGuard itself doesn't need this). Only applicable when obfuscating.

-keepclasseswithmembernames class_specification

Short for-keepclasseswithmembers,allowshrinkingclass_specification. Specifies classes and class members whose names are to be preserved, on the condition that all of the specified class members are present after the shrinking phase. For example, you may want to keep all native method names and the names of their classes, so that the processed code can still link with the native library code. Native methods that aren't used at all can still be removed. If a class file is used, but none of its native methods are, its name will still be obfuscated. Only applicable when obfuscating.

-keep, -keepclassmembers, -keepclasseswithmembers의 경우, Shirink를 하지 않습니다.

-if class_specification

Specifies classes and class members that must be present to activate the subsequent keep option (-keep,-keepclassmembers,...). The condition and the subsequent keep option can share wildcards and references to wildcards. For example, you can keep classes on the condition that classes with related names exist in your project, with frameworks like Dagger and Butterknife.

-if   class **$$ViewBinder
-keep class <1>

-printseeds [filename]

Specifies to exhaustively list classes and class members matched by the various -keep options. The list is printed to the standard output or to the given file. The list can be useful to verify if the intended class members are really found, especially if you're using wildcards. For example, you may want to list all the applications or all the applets that you are keeping.