proguard – What makes certain android classes "must -keep"?-ThrowExceptions

Exception or error:

I noticed that the “template” proguard.cfg always contains the following:

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

Why these particular classes and not others?

Is this the complete list of classes that must not be “optimized out” by ProGuard?

How to solve:

In short, those classes are in the proguard.cfg template because those classes can be declared in the AndrodiManifest.xml.

Consider this minimal application:

CustomTextView.java:

package com.example.android;

import android.content.Context;
import android.widget.TextView;

public class CustomTextView extends TextView {
    public CustomTextView(Context context) {
        super(context);
        setText("The class name of this class is not important");
    }
}

ExampleActivity.java:

package com.example.android;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class ExampleActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new CustomTextView(this));
        Log.i("ExampleActivity", "The class name of this class is important");
    }
}

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.android"
      android:versionCode="1"
      android:versionName="1.0">
    <application>
        <activity android:name=".ExampleActivity">
            <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Now, without the line

-keep public class * extends android.app.Activity

in the proguard.cfg file, proguard might be tempted to rename ExampleActivity to A. It does not know anything about AndroidManifest.xml though, so it will not touch the manifest. Since the Android OS uses class names declared in the application manifest to start an application, the Android OS will try to instantiate ExampleActivity, but that class won’t exist since proguard renamed it!

In the case of CustomTextView, it’s fine for proguard to rename it to say B, because the name of the class is not important since it is not declared in the manifest, only referenced by code that proguard will update when it changes the class name of CustomTextView.

In one way or another, all classes referenced from the template proguard.cfg file can be declared in the manifest, so proguard must not touch them.

###

Look at the ProGuard Manual. It states that -keep:

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.
 

 

Is this the complete list of classes that must not be obfuscated by
ProGuard?

If you specify -keep That doesn’t mean a lack of obfuscation. It means that it keeps those classes in your code. Because ProGuard while trying to optimize and shrink your app, it might remove certain classes if they don’t appear to be used. Don’t take my word 100%, but that’s what I read on some other SO post once upon a time.

Why these particular classes and not others?

I would assume because those classes are pretty important. And as you can see most of them are classes that extend the ones you listed. If you specify an Activity, Service, or anything else you listed, you definitely wouldn’t want it to be removed during the optimization.

Leave a Reply

Your email address will not be published. Required fields are marked *