Proguard y reflexión en Android
Acabo de usar proguard, pero las clases que estoy tratando de instanciar a través de la reflexión no funcionan.
Tengo una interfaz
- Android: cambiar el campo final estático privado usando la reflexión de java
- Anotación personalizada de Java y carga dinámica
- UnsuppotedOperationException.getCause se devuelve
- Instancia de clase abstracta con constructor oculto
- ¿Cómo utilizar la reflexión para cambiar el servicio de copia de seguridad?
Algorithm
Paso clases como esta
AlgorithmFactory.SomeClassThatExtendsAlgorithmImpl.class
La clase se instancia de este modo
public ArrayList<Algorithm> getAlgorithms(Context cnx) { ArrayList<Algorithm> list = new ArrayList<Algorithm>(); for(Class<? extends Algorithm> alg: algorithms) { try { Constructor<? extends Algorithm> c = alg.getConstructor(Context.class); list.add(c.newInstance(cnx)); } catch (IllegalArgumentException e) { Log.e(TAG, "IllegalArgumentException", e); throw new IllegalStateException("There was a problem creating the Algorithm class"); } catch (InvocationTargetException e) { Log.e(TAG, "InvocationTargetException", e); throw new IllegalStateException("There was a problem creating the Algorithm class"); } catch (InstantiationException e) { Log.e(TAG, "InstantiationException", e); throw new IllegalStateException("There was a problem creating the Algorithm class"); } catch (IllegalAccessException e) { Log.e(TAG, "IllegalAccessException", e); throw new IllegalStateException("There was a problem creating the Algorithm class"); } catch (SecurityException e) { Log.e(TAG, "SecurityException", e); throw new IllegalStateException("There was a problem creating the Algorithm class"); } catch (NoSuchMethodException e) { Log.e(TAG, "NoSuchMethodException", e); throw new IllegalStateException("There was a problem creating the Algorithm class"); } } return list; }
Aquí está mi proguard.cnf
-optimizationpasses 5 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontpreverify -verbose -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* -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 com.android.vending.licensing.ILicensingService -keepclasseswithmembernames class * { native <methods>; } -keepclasseswithmembernames class * { public <init>(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembernames class * { public <init>(android.content.Context, android.util.AttributeSet, int); } -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; } -assumenosideeffects class android.util.Log { public static *** d(...); public static *** v(...); public static *** i(...); public static *** w(...); public static *** e(...); }
- Detectar videollamada entrante en android
- ¿Cómo obtengo el nombre del método dentro de ese método?
- ¿Es posible cargar dinámicamente una biblioteca en tiempo de ejecución desde una aplicación de Android?
- Cómo moverse repetición similar-variable en declaraciones if
- Java Reflection - Obtener todos los nombres de variables de instancia de una clase
- Acceso a campos desde un objeto proxy
- Métodos de reflexión no funcionan cuando se utiliza proguard para la aplicación de Android
- Invocación de un método privado (no publicado) en la API de Android
Resuelto
Para otros que tienen este problema, debe agregar lo siguiente a proguard.cnf
-keep public class * extends com.yoursite.android.yourappname.YourClassName -keepclassmembers class * extends com.yoursite.android.yourappname.YourClassName{ public <init>(android.content.Context); }
El primer keep dice proguard para no ofuscar nombres de clase que extienden YourClassName
El segundo dice que mantener el nombre del constructor ( <init>
significa constructor) no obscurecido que tiene un único argumento de Context
y extiende YourClassName
Además, para los desarrolladores de Android que estén utilizando el atributo onClick en su archivo de layouts XML , también deberá agregar el nombre de la función en su archivo proguard.cnf.
-keepclassmembers class * { public void myClickHandler(android.view.View); }
Esto dice mantener todos los métodos llamados myClickHandler
con un único argumento View
en todas las clases. Puede restringir aún más esto utilizando la palabra clave extends como anteriormente.
espero que esto ayude.
Para la solución de clic de clic, no tiene que enumerar cada nombre de método. Tu puedes hacer:
-keepclassmembers class * { public void *(android.view.View); }
Que encuentran todos los métodos que tienen un parámetro Ver como.
- Conectar Bluestacks a Android Studio
- La navegación en modo inmersivo se vuelve pegajosa después de presionar el volumen o minimizarla