是什么让某些 Android 类“必须保留”?

发布于 2024-12-26 16:48:22 字数 606 浏览 1 评论 0原文

我注意到“模板”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 不得“优化”的类的完整列表吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

饮湿 2025-01-02 16:48:23

简而言之,这些类位于 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 来说,混淆器可以将其重命名为 B,因为类的名称并不重要,因为它没有在清单中声明,只是由 proguard 在更改 CustomTextView 的类名时更新的代码引用。

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

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.

南薇 2025-01-02 16:48:23

请参阅 ProGuard 手册。它指出-keep

指定类和类成员(字段和方法)
保留作为代码的入口点。例如,为了保持
一个应用程序,您可以指定主类及其主类
方法。为了处理库,您应该公开指定所有
可访问的元素。
 

 

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

如果您指定 -keep 这并不意味着没有混淆。这意味着它将这些类保留在您的代码中。因为 ProGuard 在尝试优化和缩小您的应用程序时,可能会删除某些似乎未使用的类。不要百分百相信我的话,但这就是我从前在其他一些 SO 帖子上读到的内容。

为什么选择这些特定的类而不是其他类?

我想是因为这些课程非常重要。正如您所看到的,它们中的大多数都是扩展您列出的类。如果您指定 ActivityService 或列出的任何其他内容,您肯定不希望它在优化过程中被删除。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文