Что делает определенные классы Android "must -keep"? - PullRequest
22 голосов
/ 14 января 2012

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

27 голосов
/ 26 января 2012

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

Посмотрите на ProGuard Manual.В нем говорится, что -keep:

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

Это полный список классов, которые не должны быть запутаны ProGuard?

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

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

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

...