Как сохранить перечисления при работе с proguard? - PullRequest
0 голосов
/ 14 мая 2019

Я разработал приложение для Android, которое использует Enums во многих модулях.Сейчас я пытаюсь защитить свое приложение от реверс-инжиниринга, для этого я включил Proguard в своем приложении, но проблема заключается в том, что после включения Proguard происходит сбой моего приложения, где бы я ни использовал Enums.Я создал следующий класс для определения всех перечислений

package app.mypackagename.utils;

import android.content.Context;

public class EnumUtils {

    public static enum AppDomain {
        LIVE, STAGING, MOCK
    }

    public static enum UserRole {
        CUSTOMER, ADMIN;

    }
    public static enum Module {
        REGISTRATION, PRODUCT
    }

}

Enum "UserRole" используется внутри класса модели "Пользователь"

package app.mypackagename.flavors.models;


import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

import app.mypackagename.utils.EnumUtils;

public class User {
    @SerializedName("sulLevelcode")
    public String sulLevelcode;

    public  EnumUtils.UserRole userRole = null;
}

При успешном входе в систему я проверяю пользователяроль с использованием следующего кода

                            Gson gson = new Gson();
                            Type listType = new TypeToken<User>() {
                            }.getType();
                            onlineUser = ((User) gson.fromJson(taskItem.getRawResponse(),
                                    listType));
                            onlineUser.userID = userId;
                            if (onlineUser.sulLevelcode.equalsIgnoreCase(Constants.LEVEL_CODE_CUSTOMER)) {
                                onlineUser.userRole = EnumUtils.UserRole.CUSTOMER;
                            }

Но приложения всегда аварийно завершают работу при доступе к значению Enum.

Ниже приведена трассировка сбоя

 java.lang.AssertionError: java.lang.NoSuchFieldException: CUSTOMER
    at b.b.c.b.a.ja$a.<init>(:808)
    at b.b.c.b.a.V.a(:834)
    at b.b.c.p.a(:423)
    at b.b.c.b.a.p.a(:115)
    at b.b.c.b.a.p.a(:164)
    at b.b.c.b.a.p.a(:100)
    at b.b.c.p.a(:423)
    at b.b.c.p.a(:886)
    at b.b.c.p.a(:852)
    at b.b.c.p.a(:801)
    at app.mypackagename.activities.k.a(:355)
    at app.mypackagename.f.c.a(:442)
    at app.mypackagename.f.c.a(:43)
    at app.mypackagename.f.b.a(:288)
    at app.mypackagename.f.b.a(:271)
    at b.c.a.b.m.c(:107)
    at b.c.a.b.m.b(:141)
    at b.c.a.b.m.a(:128)
    at b.c.b.A.a(:456)
    at b.c.a.b.m.c(:107)
    at b.c.a.b.m.b(:141)
    at b.c.a.b.m.a(:128)
    at b.c.b.r.run(:246)
    at b.c.a.y$d.run(:60)
    at android.os.Handler.handleCallback(Handler.java:761)
    at android.os.Handler.dispatchMessage(Handler.java:98)
    at android.os.Looper.loop(Looper.java:156)
    at android.app.ActivityThread.main(ActivityThread.java:6577)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:986)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)
 Caused by: java.lang.NoSuchFieldException: CUSTOMER
    at java.lang.Class.getField(Class.java:1549)
    at b.b.c.b.a.ja$a.<init>(:797)
    at b.b.c.b.a.V.a(:834) 
    at b.b.c.p.a(:423) 
    at b.b.c.b.a.p.a(:115) 
    at b.b.c.b.a.p.a(:164) 
    at b.b.c.b.a.p.a(:100) 
    at b.b.c.p.a(:423) 
    at b.b.c.p.a(:886) 
    at b.b.c.p.a(:852) 
    at b.b.c.p.a(:801) 
    at app.mypackagename.activities.k.a(:355) 
    at app.mypackagename.f.c.a(:442) 
    at app.mypackagename.f.c.a(:43) 
    at app.mypackagename.f.b.a(:288) 
    at app.mypackagename.f.b.a(:271) 
    at b.c.a.b.m.c(:107) 
    at b.c.a.b.m.b(:141) 
    at b.c.a.b.m.a(:128) 
    at b.c.b.A.a(:456) 
    at b.c.a.b.m.c(:107) 
    at b.c.a.b.m.b(:141) 
    at b.c.a.b.m.a(:128) 
    at b.c.b.r.run(:246) 
    at b.c.a.y$d.run(:60) 
    at android.os.Handler.handleCallback(Handler.java:761) 
    at android.os.Handler.dispatchMessage(Handler.java:98) 
    at android.os.Looper.loop(Looper.java:156) 
    at android.app.ActivityThread.main(ActivityThread.java:6577) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:986) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)  

Ниже приведен файл правил proguard

# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# 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 *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

-dontwarn com.alcorlink.**
-dontwarn com.google.android.**
-dontwarn androidx.media.**

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-keep class app.app.mypackagename.utils.EnumUtils { *; }

##---------------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
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class app.mypackagename.flavors.models.User.** { <fields>; }

# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer

# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}

##---------------End: proguard configuration for Gson  ----------

Я перепробовал почти все решения, доступные в Stack Overflow, но я не могу решить эту проблему.

Некоторые способы, которые я пробовал

    --keep class app.mypackagename.utils.EnumUtils{ *; }

    -keep class app.mypackagename.flavors.models.User.** { *; }

    -keepclassmembers enum * {
         public static **[] values();
         public static ** valueOf(java.lang.String);
     }
    -keepclassmembers enum * { *; }
    -keepclassmembers enum app.mypackagename.** { *; }
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-keep public enum app.mypackagename.utils.EnumUtils** {
    **[] $VALUES;
    public *;
}
-keepattributes AppDomain
-keepattributes UserRole

Может кто-нибудь пожалуйстапомоги мне с этим.Любая помощь будет оценена.

...