setapplicationname library google for apis android google-api google-drive-sdk proguard google-api-java-client

android - library - google finance api java



La API de Google Drive no funciona bien con ProGuard(NPE) (6)

Últimamente ha habido algunas actualizaciones en GooglePlayServices. No me gusta la nueva API. Tenía los mismos problemas.

No pude compilar la aplicación firmada con proguard. La plantilla de progreso de Google no funcionó para mí.

Agrego estas cuatro líneas a mi configuración de programa y está funcionando:

-dontwarn com.google.android.gms.** -keep interface com.google.** { *; } -keep class * extends com.google.api.client.json.GenericJson {*;} -keep class com.google.api.services.drive.** {*;}

Esto es extraño. Versión anterior de google-api-services-drive-v2 compilada sin ningún problema.

Estoy usando la última versión en este momento: google-api-services-drive-v2-rev47-1.12.0-beta.jar

Actualmente, tengo experiencia que, un fragmento de código, que hace uso de la API de Google Drive funciona bien sin introducir ProGuard.

Sin embargo, después de presentar ProGuard, aparece el siguiente error de tiempo de ejecución.

at java.lang.Thread.run(Thread.java:856) Caused by: java.lang.NullPointerException at com.google.api.client.util.Types.getActualParameterAtPosition(Types.java:329) at com.google.api.client.util.Types.getIterableParameter(Types.java:309) at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:546) at com.google.api.client.json.JsonParser.parse(JsonParser.java:350) at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:586) at com.google.api.client.json.JsonParser.parse(JsonParser.java:289) at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:76) at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:71) at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:491) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:456) at com.jstock.c.b.a(CloudFile.java:136)

Tenga en cuenta que el bloqueo se produce en mi código (que es com.jstock.cba si vuelvo a rastrear utilizando mapping.txt)

// request is Files.List FileList files = request.execute();

En mi proguard, pensé que tener las siguientes 2 instrucciones clave, capaz de evitar que se produjera el bloqueo: le digo a ProGuard que nunca toque las bibliotecas de jackson y Google.

-keep class org.codehaus.** { *; } -keep class com.google.** { *; } -keep interface org.codehaus.** { *; } -keep interface com.google.** { *; }

Pero eso no funciona. NPE todavía sucede en Types.java

Tenga en cuenta que, tuve otro intento es que, pensé que el proceso de ofuscación causa NPE. Por lo tanto, trato de deshabilitarlo usando -dontobfuscate . Pero esta vez, no podré generar un archivo APK, y obtendré un mensaje de error popular: La conversión al formato Dalvik falló con el error 1

Aquí está la configuración del programa que causa NPE en la API de Google Drive.

-optimizationpasses 1 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontpreverify -verbose -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # Comment out the following line, will cause popular "Conversion to Dalvik format failed with error 1" ##-dontobfuscate -dontwarn sun.misc.Unsafe -dontwarn com.google.common.collect.MinMaxPriorityQueue -dontwarn javax.swing.** -dontwarn java.awt.** -dontwarn org.jasypt.encryption.pbe.** -dontwarn java.beans.** -dontwarn org.joda.time.** -dontwarn com.google.android.gms.** -dontwarn org.w3c.dom.bootstrap.** -dontwarn com.ibm.icu.text.** -dontwarn demo.** # Hold onto the mapping.text file, it can be used to unobfuscate stack traces in the developer console using the retrace tool -printmapping mapping.txt # Keep line numbers so they appear in the stack trace of the develeper console -keepattributes *Annotation*,EnclosingMethod,SourceFile,LineNumberTable -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 -keep class android.support.v4.app.** { *; } -keep interface android.support.v4.app.** { *; } -keep class com.actionbarsherlock.** { *; } -keep interface com.actionbarsherlock.** { *; } # https://sourceforge.net/p/proguard/discussion/182456/thread/e4d73acf -keep class org.codehaus.** { *; } -keep class com.google.** { *; } -keep interface org.codehaus.** { *; } -keep interface com.google.** { *; } -assumenosideeffects class android.util.Log { public static int d(...); public static int i(...); public static int e(...); public static int v(...); } -keepclasseswithmembernames class * { native <methods>; } -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet, int); } -keepclassmembers class * extends android.app.Activity { public void *(android.view.View); } -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(...); } -keepclasseswithmembers class com.google.common.base.internal.Finalizer{ <methods>; }

¿Hay algo más que pueda probar?

No estoy seguro de que pueda deberse a la combinación de las bibliotecas. (Aunque las cosas funcionan bastante bien sin presentar ProGuard)

Si miro la ubicación del fallo NPE (Types.getActualParameterAtPosition (Types.java:329))

private static Type getActualParameterAtPosition(Type type, Class<?> superClass, int position) { ParameterizedType parameterizedType = Types.getSuperParameterizedType(type, superClass); Type valueType = parameterizedType.getActualTypeArguments()[position]; // this is normally a type variable, except in the case where the class of iterableType is // superClass, e.g. Iterable<String> if (valueType instanceof TypeVariable<?>) { Type resolve = Types.resolveTypeVariable(Arrays.asList(type), (TypeVariable<?>) valueType); if (resolve != null) { return resolve; } } return valueType; }

Sospecho que Types.getSuperParameterizedType devuelve null . Por lo tanto, busco más en Types.getSuperParameterizedType .

public static ParameterizedType getSuperParameterizedType(Type type, Class<?> superClass) { if (type instanceof Class<?> || type instanceof ParameterizedType) { outer: while (type != null && type != Object.class) { Class<?> rawType; if (type instanceof Class<?>) { // type is a class rawType = (Class<?>) type; } else { // current is a parameterized type ParameterizedType parameterizedType = (ParameterizedType) type; rawType = getRawClass(parameterizedType); // check if found Collection if (rawType == superClass) { // return the actual collection parameter return parameterizedType; } if (superClass.isInterface()) { for (Type interfaceType : rawType.getGenericInterfaces()) { // interface type is class or parameterized type Class<?> interfaceClass = interfaceType instanceof Class<?> ? (Class<?>) interfaceType : getRawClass( (ParameterizedType) interfaceType); if (superClass.isAssignableFrom(interfaceClass)) { type = interfaceType; continue outer; } } } } // move on to the super class type = rawType.getGenericSuperclass(); } } return null; }

¿Cuál es la posible causa raíz que puede hacer que getSuperParameterizedType devuelva null , después de que ProGuard lo haya procesado?


¿Su código usa algo que implementa Serializable? Todos aquellos deben ser excluidos también.


El método Types.getSuperParameterizedType se basa en información sobre genéricos. Los genéricos se borran en Java. El compilador solo los agrega como atributos de anotación, la JVM los ignora y ProGuard los descarta a menos que usted lo indique. Así que esto podría ayudar:

-keepattributes *Annotation*


El primer mantenimiento de una clase no significa no tocarla. Significa que no cambie su nombre y utilícelo como base para determinar si otras clases no están referenciadas y se pueden eliminar.

La optimización sigue ocurriendo, lo cual es probable que sea su problema. El siguiente paso que haría es intentar con: -dontoptimizar

Esto debería hacer que sus otras optimizaciones sean ignoradas.

Por cierto, no estoy seguro de qué versión de SDK está utilizando. Estoy usando 15, 20 es lo último, y se crea un archivo proguard-project.txt con el proyecto. Las opciones de optimización que utiliza son:

-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*

Si la desactivación de la optimización hace que se ejecute, tal vez la desactivación de todas las optimizaciones (eso es lo que hace el SDK), también le permitirá realizar la optimización.



Una combinación de lo siguiente me ha funcionado:

-keep class com.google.** { *;} -keep interface com.google.** { *;} -dontwarn com.google.** -dontwarn sun.misc.Unsafe -dontwarn com.google.common.collect.MinMaxPriorityQueue -keepattributes *Annotation*,Signature -keep class * extends com.google.api.client.json.GenericJson { *; } -keep class com.google.api.services.drive.** { *; }

Esto proporcionó una solución compatible con un programa de trabajo para un proyecto reciente de Google Drive.

Sin embargo, no se puede tomar todo el crédito por esta solución, originalmente se encuentra en este enlace here