什么使某些Android类“必须 - 保持”?

时间:2012-01-13 22:54:38

标签: android proguard

我注意到“模板”proguard.cfg始终包含以下内容:

-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

为什么这些特殊课程而不是其他课程?

这是ProGuard不能“优化”的完整类列表吗?

2 个答案:

答案 0 :(得分:26)

简而言之,这些类在proguard.cfg模板中,因为这些类可以在AndrodiManifest.xml中声明。

考虑这个最小的应用程序:

<强> 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>

现在,没有线

-keep public class * extends android.app.Activity
在proguard.cfg文件中,proguard可能会将ExampleActivity重命名为A虽然它对AndroidManifest.xml一无所知,但它不会触及清单。由于Android操作系统使用在应用程序清单中声明的​​类名来启动应用程序,因此Android操作系统将尝试实例化ExampleActivity,但由于proguard重命名它,该类将不存在!

对于CustomTextView,proguard将其重命名为B是好的,因为类的名称并不重要,因为它没有在清单中声明,只是由代码引用当proguard更改CustomTextView的类名时会更新。

以这种或那种方式,从模板proguard.cfg文件引用的所有类都可以在清单中声明,因此proguard不能触及它们。

答案 1 :(得分:2)

查看ProGuard Manual。它声明-keep

  

指定要使用的类和类成员(字段和方法)   保留为代码的入口点。例如,为了保持   在应用程序中,您可以指定主类及其主要类   方法。要处理库,您应该公开指定所有库   无障碍元素。   

  

这是不能被混淆的类的完整列表   ProGuard的?

如果指定-keep这并不意味着缺乏混淆。这意味着它将这些类保留在您的代码中。因为ProGuard在尝试优化和缩小您的应用时,如果它们似乎没有被使用,它可能会删除某些类。不要100%接受我的话,但这是我曾经在其他一些SO帖子上读过的。

  

为什么这些特殊课程而不是其他课程?

我会假设,因为这些课程非常重要。正如您所看到的,大多数是extend列出的类。如果您指定了ActivityService或您列出的任何其他内容,那么您绝对不希望在优化过程中将其删除。