enums - 如何让枚举在启用 proguard 的情况下工作?
问题描述
我开发了一个在许多模块中使用 Enums 的 android 应用程序。现在我正试图保护我的应用程序免受逆向工程的影响,为此我在我的应用程序中启用了 proguard,但问题是在我使用 Enums 的任何地方启用 proguard 后我的应用程序崩溃。我创建了以下类来定义所有枚举
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
}
}
在模型类“User”中使用枚举“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
有人可以帮我解决这个问题。任何帮助将不胜感激。
解决方案
我有同样的问题,但将此行添加到我的 proguard-rules.pro 工作 -
-keep class app.mypackagename.constants.* { <fields>; }.
其中“app.mypackagename.constants”是我所有枚举所在的包。
推荐阅读
- angular - 如何以角度获取表格中选定的行值?
- java - Primefaces 6.2 PhotoCam - Firefox / Safari 的网络摄像头错误
- swift - 尝试快速停止计时器对象时出现致命错误
- python - 启动 dask.distributed Client/LocalClient 后无法捕获 KeyboardInterrupt 异常
- android - Cordova:自适应图标显示前景图像,但不显示背景颜色
- mongodb - Apache Drill - 首次启动时间较长
- c - 从现有 C 文件、头文件和 makefile 创建 Visual Studio 项目
- mongodb - 带有 upsert false 的 Mongo updateOne 不起作用?
- php - 匹配数据并使用 IF 语句打印数据
- python - 在 python 中使用 mysql 连接器从 mysql 数据库中正确获取 blob