2012-01-13 3 views
21

私は、「テンプレート」はproguard.cfg常に次が含まれていることに気づい:特定のアンドロイドクラスを "keep-keep"にするにはどうすればよいですか?

-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によって「最適化」されてはならないクラスの完全なリストですか?

答えて

24

つまり、これらのクラスはAndrodiManifest.xmlで宣言できるため、proguard.cfgテンプレートに含まれています。

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:

は、この最小限のアプリケーションを考えてみましょうProGuardの中

-keep public class * extends android.app.Activity 

ラインなし今

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

、。cfgファイルの場合、ExampleActivityの名前をAに変更したくなるかもしれません。 AndroidManifest.xmlについては何も知らないので、マニフェストには触れません。 Android OSはアプリケーションマニフェストで宣言されたクラス名を使用してアプリケーションを起動するため、Android OSはExampleActivityをインスタンス化しようとしますが、proguardの名前が変更されてからそのクラスは存在しません。

それはマニフェストで宣言されていないため、クラスの名前は唯一、それが変化したときにProGuardを更新するコードによって参照され、重要ではありませんのでCustomTextViewの場合、それは、Bを言って、それを名前を変更するProGuardのための罰金ですクラス名はCustomTextViewです。

いずれかの方法で、テンプレートproguard.cfgファイルから参照されるすべてのクラスをマニフェストで宣言できるため、proguardはそれらに触れてはいけません。

+0

私の質問を理解し、このような素晴らしい答えを提供してくれてありがとう。すでに驚くべきことがない限り、あなたの答えは+50を受け入れる予定です。ここではフォローアップの質問:** '#1' **私はあなたの答えから' -keep'も "最適化"するだけでなく、マッピングにも影響することを正しく理解していますか? ** '#2' ** Proguardの将来のバージョンでAndroidManifest.xmlがサポートされている場合、上記のクラスでは' -keep'は必要なくなります。 –

+0

** '#1' **:「マッピング」が何を意味するかは完全にはわかりません。 "名前の変更"を意味するならば、 '-keep'はproguardがクラスを削除するだけでなくクラスの名前を変更することも防ぐ。 AndroidManifestに関連する何かを「マッピング」することによって意味がある場合。'-keep'は' AndroidManifest.xml'と全く関係がありません。なぜなら、ちょうど '-keep'が最初に必要な理由です(#2の答えを見てください)。 ** '#2' **そう、proguardがAndroidManifest.xmlのセマンティクスについて知っていれば(それを変更する方法)、' -keep'は必要ありません。 –

2

ProGuard Manualをご覧ください。

があなたのコードへのエントリポイントとして保存 するクラスおよびクラスメンバー(フィールドやメソッド)を指定:それは-keepと述べています。たとえば、 をアプリケーションに保つには、メインのクラスとそのメインの メソッドを指定できます。ライブラリを処理するには、アクセシブルな要素をすべて公開して と指定する必要があります。

これは ProGuardので難読化されてはならないクラスの一覧ですか?

-keepを指定した場合、難読化の不足は意味しません。つまり、それらのクラスはコード内に保持されます。 ProGuardはアプリケーションの最適化と縮小を行うため、使用されていないと思われる特定のクラスを削除する可能性があります。私の言葉を100%使ってはいけませんが、それは私が他のSOの投稿を一度に読んだものです。

なぜこれらの特定のクラスと他のものはありませんか?

これらのクラスはかなり重要だと思います。そして、あなたが見ることができるように、それらのクラスのほとんどはextendあなたがリストしたものです。 Activity,Serviceなどを指定した場合は、最適化中に削除されたくないことは間違いありません。

+0

ありがとうございますが、私が挙げた特定の** Android **クラスに固有の回答を探しています。例えば、**は何を 'BroadcastReceiver'に' -keep'する必要がありますか? 「かなり重要」と言っても何も教えてくれません... –

+0

「BroadcastReceiver」の理由は、(他のJavaコードを介して) 'BroadcastReceiver'クラスが使用されていないことがよくあります。マニフェストで参照されています。それは使用されているが、「Proguard」はそのことを認識しないので、「Proguard」はそれを削除しないように '-keep'する必要があります。私は事実についてこれを知らないが、それは[Proguard Manual](http://proguard.sourceforge.net/index.html#)を読んで理解することだけである。 – Jakar

+0

ありがとうございます。私はマニュアルを読みましたが、なぜ** ADT **がテンプレート 'proguard.cfg'にこれらのクラスを選んだのか理解できません。 '-keep'の記述は次のようになります:"クラスとクラスメンバ(フィールドとメソッド)を**エントリポイント**としてあなたのコードに保存するよう指定します。 "ところで、上に挙げたクラスから派生したクラスは保持されているだけでなく、あまりにも曖昧です**。 –