2012-01-13 10 views
21

me di cuenta de que la "plantilla" proguard.cfg siempre contiene lo siguiente:¿Qué hace que ciertas clases de Android sean "imprescindibles"?

-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 

¿Por qué estas clases particulares y no otros?

¿Es esta la lista completa de las clases que no deben ser "optimizadas" por ProGuard?

Respuesta

24

En resumen, esas clases están en la plantilla proguard.cfg porque esas clases se pueden declarar en el AndrodiManifest.xml.

considerar esta aplicación mínima:

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> 

Ahora, sin la línea

-keep public class * extends android.app.Activity 

en el Proguard.archivo cfg, proguard podría tener la tentación de cambiar el nombre ExampleActivity al A. Sin embargo, no sabe nada de AndroidManifest.xml, por lo que no tocará el manifiesto. Dado que el sistema operativo Android usa nombres de clase declarados en el manifiesto de la aplicación para iniciar una aplicación, el sistema operativo Android intentará crear una instancia de ExampleActivity, pero esa clase no existirá ya que proguard la renombró.

En el caso de CustomTextView, que está bien para Proguard para cambiar el nombre con decir B, porque el nombre de la clase no es importante, ya que no se ha declarado en el manifiesto, sólo se hace referencia por código que Proguard actualizará cuando cambia el nombre de clase de CustomTextView.

De una forma u otra, todas las clases a las que se hace referencia desde el archivo proguard.cfg de la plantilla pueden declararse en el manifiesto, por lo que proguard no debe tocarlas.

+0

Gracias por entender mi pregunta y por brindar una respuesta tan buena. +1 ya y planeo aceptar +50 tu respuesta a menos que surja algo sorprendente. Ahora las preguntas de seguimiento: ** '# 1.' ** ¿Entiendo correctamente de su respuesta que' -keep' también afecta el mapeo, no solo "optimizando"? ** '# 2.' ** Si las futuras versiones de Proguard son compatibles con AndroidManifest.xml, entonces' -keep' ya no será necesario para las clases antes mencionadas. –

+0

** '# 1.' **: No estoy del todo seguro de lo que quiere decir con" mapeo ". Si quiere decir "cambiar el nombre de las clases", entonces sí, '-keep' evita que procure no solo eliminar la clase sino también cambiar el nombre de la clase. Si "mapear" significa algo relacionado con AndroidManifest.xml, luego no, '-keep' no tiene ninguna relación con' AndroidManifest.xml' en absoluto, que es exactamente la razón por la cual '-keep' es necesario en primer lugar (ver respuesta al # 2). ** '# 2.' ** Sí, si proguard supiera sobre la semántica de AndroidManifest.xml (y cómo modificarla), entonces' -keep' no sería necesario. –

2

Mire el ProGuard Manual. Afirma que -keep:

Especifica las clases y los miembros de la clase (campos y métodos) para ser preservado como puntos de entrada a su código. Por ejemplo, para mantener una aplicación, puede especificar la clase principal junto con su método principal . Para procesar una biblioteca, debe especificar todos los elementos accesibles públicamente .

¿Es esta la lista completa de las clases que no debe ser ofuscado por ProGuard?

Si especifica -keep Eso no significa una falta de ofuscación. Significa que mantiene esas clases en tu código. Debido a que ProGuard trata de optimizar y reducir su aplicación, puede eliminar ciertas clases si no parecen ser utilizadas. No tome mi palabra al 100%, pero eso es lo que leí en alguna otra publicación SO de vez en cuando.

¿Por qué estas clases particulares y otras no?

Asumiría porque esas clases son bastante importantes. Y como puede ver, la mayoría de ellos son clases que figuran en extend. Si especifica un Activity, Service, o cualquier otra cosa que haya enumerado, definitivamente no querrá que se elimine durante la optimización.

+0

Gracias pero estoy buscando una respuesta que sea específica para las clases de ** Android ** particulares que enumeré. Por ejemplo, ** ¿qué ** hace 'BroadcastReceiver' must' -keep'? Declarar "bastante importante" no me dice nada ... –

+0

Bueno, yo diría que la razón de 'BroadcastReceiver' puede ser que muchas veces una clase' BroadcastReceiver' no parece ser utilizada (a través de otro código Java), pero se hace referencia en tu manifiesto. Lo que significa que se usa, pero 'Proguard' no reconoce eso, por lo que debes' 'mantenerlo' para que' Proguard' no lo elimine. No sé nada de esto por un hecho, eso es lo que entiendo después de leer el ['Proguard Manual'] (http://proguard.sourceforge.net/index.html#). – Jakar

+0

Gracias. Leí el manual pero todavía no entiendo por qué ** ADT ** eligió estas clases para estar allí en la plantilla 'proguard.cfg'. La descripción de '-keep' dice:" Especifica las clases y los miembros de la clase (campos y métodos) que se conservarán como ** puntos de entrada ** a su código ". Por cierto, las clases derivadas de las enumeradas anteriormente no solo se guardan, sino que ** también están ocultas **. –

Cuestiones relacionadas