Ответы на ретро-фит не работают с профессиональным защитником

У меня есть приложение, которое использует модификацию для вызовов API. Я пытаюсь добавить профессиональную защиту, но мне не удается выполнить один из ответов.

FATAL EXCEPTION: main Process: com.karriapps.smartsiddurlite, PID: 13387
  java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.List.get(int)' on a null object reference
       at com.karriapps.smartsiddur.util.b$3.a(SourceFile:255)
       at com.karriapps.smartsiddur.util.b$3.success(SourceFile:252)
       at retrofit.CallbackRunnable$1.run(SourceFile:45)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:135)
       at android.app.ActivityThread.main(ActivityThread.java:5431)
       at java.lang.reflect.Method.invoke(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:914)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)

Я точно знаю, что ответ содержит данные, но, похоже, он не может их десериализовать.

Вот код, который не работает

mElavationService.getElevation(new ElavationService.LatLng(mLocation.getLatitude(), mLocation.getLongitude()),
            BING_KEY,
            new Callback<BingElevationResponse>() {
                @Override
                public void success(BingElevationResponse bingElevationResponse, Response response) {
                    double elavation = bingElevationResponse.getResourceSets().get(0)
                            .getResources().get(0).getOffsets().get(0);
                    if (elavation > 0) {
                        mLocation.setElevation(elavation);
                    } else {
                        mLocation.setElevation(0);
                    }
                    responsesCount++;
                    if (requestsCount == responsesCount) {
                        setZmanimToLocation(mLocation);
                    }
                }

                @Override
                public void failure(RetrofitError error) {
                    Log.e(TAG, error.toString(), error.fillInStackTrace());
                    mLocation.setElevation(0);
                    responsesCount++;
                    if (requestsCount == responsesCount) {
                        setZmanimToLocation(mLocation);
                    }
                }
            });

И мой прогард файл

# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/orel/Android/Sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Proguard Configuration for Realm (http://realm.io)
# For detailed discussion see: https://groups.google.com/forum/#!topic/realm-java/umqKCc50JGU
# Additionally you need to keep your Realm Model classes as well
# For example:
# -keep class com.yourcompany.realm.** { *; }

-keep class io.realm.annotations.RealmModule
-keep @io.realm.annotations.RealmModule class *
-keep class io.realm.internal.Keep
-keep @io.realm.internal.Keep class *
-keepnames public class * extends io.realm.RealmObject
-dontwarn javax.**
-dontwarn io.realm.**

-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose

# Allow obfuscation of android.support.v7.internal.view.menu.**
# to avoid problem on Samsung 4.2.2 devices with appcompat v21
# see https://code.google.com/p/android/issues/detail?id=78377
-keep class !android.support.v7.internal.view.menu.**,android.support.** {*;}


# Crashlytics 2.+

-keep class com.crashlytics.** { *; }
-keep class com.crashlytics.android.**
-keepattributes SourceFile, LineNumberTable, *Annotation*

# If you are using custom exceptions, add this line so that custom exception types are skipped during obfuscation:
-keep public class * extends java.lang.Exception

# In App Billing
-keep class com.android.vending.billing.**

## Google Play Services 4.3.23 specific rules ##
## https://developer.android.com/google/play-services/setup.html#Proguard ##

-keep class * extends java.util.ListResourceBundle {
    protected Object[][] getContents();
}

-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
    public static final *** NULL;
}

-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
    @com.google.android.gms.common.annotation.KeepName *;
}

-keepnames class * implements android.os.Parcelable {
    public static final ** CREATOR;
}

## GSON 2.2.4 specific rules ##

# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

-keepattributes EnclosingMethod

# Gson specific classes
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }

## Joda Time 2.3

-dontwarn org.joda.convert.**
-dontwarn org.joda.time.**
-keep class org.joda.time.** { *; }
-keep interface org.joda.time.** { *; }

# OkHttp
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }
-dontwarn com.squareup.okhttp.**

# Retrofit 1.X

-keep class retrofit.** { *; }
-keep class retrofit.http.** { *; }
-keep class retrofit.client.** { *; }
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }

-dontwarn com.squareup.okhttp.**
-dontwarn okio.**
-dontwarn retrofit.**
-dontwarn rx.**

-keepclasseswithmembers class * {
    @retrofit.http.* <methods>;
}

# If in your rest service interface you use methods with Callback argument.
-keepattributes Exceptions

#support design
-dontwarn android.support.design.**
-keep class android.support.design.** { *; }
-keep interface android.support.design.** { *; }
-keep public class android.support.design.R$* { *; }

# http://stackoverflow.com/questions/29679177/cardview-shadow-not-appearing-in-lollipop-after-obfuscate-with-proguard/29698051
-keep class android.support.v7.widget.RoundRectDrawable { *; }

# mixpanel
-dontwarn com.mixpanel.**

# for play services
-dontwarn org.apache.http.**
-dontwarn android.net.http.AndroidHttpClient
-dontwarn com.google.android.gms.**

##---------------Begin: proguard configuration for Gson  ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

# Gson specific classes
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-keep class com.karriapps.smartsiddur.model.response.** { *; }
-keepnames public class com.karriapps.smartsiddur.model.response.**

# debug
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable

Изменить: я добавил сам класс pojo

public class BingElevationResponse {

    private List<ResourceSet> resourceSets;

    public List<ResourceSet> getResourceSets() {
        return resourceSets;
    }

    public class ResourceSet {
        private List<Resource> resources;

        public List<Resource> getResources() {
            return resources;
        }
    }

    public class Resource {
        private List<Integer> elevations;

        public List<Integer> getOffsets() {
            return elevations;
        }
    }
}

Это путь

com.karriapps.smartsiddur.model.response.BingElevationResponse

Я был бы очень признателен за помощь муравья. Спасибо.


person orelzion    schedule 01.02.2016    source источник
comment
вы говорите, что это не удалось с одним из ответов. Можете ли вы указать полное имя класса, используемого для разбора json этого ответа? и попробуйте сохранить этот класс и его поля явно или, что еще лучше, используйте аннотации (@Serializedname for gson) для сопоставления имен с именами полей ответа json.   -  person Bhargav    schedule 02.02.2016
comment
Использование аннотаций лучше? я попробую это   -  person orelzion    schedule 02.02.2016
comment
да, конечно, тогда gson не нужно размышлять, чтобы получить имена полей таким образом, когда имена полей запутаны, это не влияет на имена полей json, используемые для psrsing, поскольку gson будет использовать имена в аннотации   -  person Bhargav    schedule 02.02.2016
comment
Ну, это не помогло. Я добавил аннотации, но он все равно вылетает с тем же исключением   -  person orelzion    schedule 02.02.2016
comment
ах, это из-за внутренних классов, попробуйте реорганизовать класс ресурсов в отдельный файл класса, или вам нужно добавить его, чтобы он оставался таким -keep class com.karriapps.smartsiddur.model.response. BingElevationResponse$Resource, я бы рекомендовал провести рефакторинг в надлежащий файл класса   -  person Bhargav    schedule 02.02.2016
comment
если вы решили это, можете ли вы сказать, какое из решений, которые я дал, действительно устранило вашу проблему, я добавлю его в свой ответ, чтобы помочь будущим читателям   -  person Bhargav    schedule 03.02.2016
comment
Конечно, я использовал аннотации, как вы предложили, причина, по которой это сначала мне не помогло, заключается в том, что я нажимал кнопку «Выполнить» после изменения только файла pro guard, или это фактически не перестраивало приложение. После того, как я это понял, я запустил перестройку, и это сработало.   -  person orelzion    schedule 03.02.2016


Ответы (1)


Если вы используете gson jackson или любые подобные библиотеки синтаксического анализатора json (я думаю, что модификация использует одну из них внутри, я не уверен), вам нужно -keep все классы Pojo И их ПОЛЯ и их НАЗВАНИЯ!

ИЗМЕНИТЬ

Добавление аннотаций @SerializedName (в случае gson) к полям класса java pojo также помогает, поскольку тогда gson не нужно отражать и получать имена полей (которые изменяются proguard, и поэтому gson будет использовать неправильные имена полей json для анализа json). Также для того, чтобы аннотация работала, вам также необходимо добавить -keepattributes *Annotation* в свои правила proguard.

person Bhargav    schedule 02.02.2016
comment
Спасибо. Если вы можете увидеть нижнюю часть моего файла pro guard, я попытался включить его -keep class com.karriapps.smartsiddur.model.response.** { ; } -keepnames общедоступный класс com.karriapps.smartsiddur.model.response.* - person orelzion; 02.02.2016