Подтвердить что ты не робот

Что делает определенные классы андроидов "must -keep"?

Я заметил, что "шаблон" 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?

4b9b3361

Ответ 1

Короче говоря, эти классы находятся в шаблоне 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 не должен трогать их.

Ответ 2

Посмотрите ProGuard Manual. В нем указано, что -keep:

Определяет классы и члены класса (поля и методы), которые должны быть сохраняются как точки входа в ваш код. Например, чтобы сохранить приложение, вы можете указать основной класс вместе с его основным метод. Чтобы обработать библиотеку, вы должны указать все публично доступных элементов.

Является ли это полным списком классов, которые не должны быть запутаны ProGuard?

Если вы укажете -keep Это не означает отсутствие обфускации. Это означает, что он сохраняет эти классы в вашем коде. Поскольку ProGuard пытается оптимизировать и сокращать ваше приложение, он может удалить определенные классы, если они не используются. Не принимайте слово 100%, но это то, что я читал на каком-то другом посту SO когда-то.

Почему эти конкретные классы, а не другие?

Я бы предположил, что эти классы очень важны. И, как вы видите, большинство из них - это классы, которые extend те, которые вы указали. Если вы укажете Activity, Service или что-то еще, что вы указали, вы определенно не захотите, чтобы он был удален во время оптимизации.