提问人:muetzenflo 提问时间:2/3/2017 最后编辑:muetzenflo 更新时间:10/28/2021 访问量:3287
仅使用 Proguard:无法初始化 DaoConfig => ArrayIndexOutOfBoundsException
Only using Proguard: Could not init DaoConfig => ArrayIndexOutOfBoundsException
问:
我正在使用以下 ProGuard 规则:
-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao { *; } -keep class **$Properties -keep class org.greenrobot.greendao.** -keepclassmembers class org.greenrobot.greendao.** { *; } # If you do not use SQLCipher: -dontwarn org.greenrobot.greendao.database.** # If you do not use RxJava: -dontwarn rx.**
启动应用程序时,我收到以下崩溃日志:
java.lang.RuntimeException: Unable to create application my.app.package.MyApplication: org.greenrobot.greendao.DaoException: Could not init DAOConfig at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4569) at android.app.ActivityThread.access$1500(ActivityThread.java:148) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5272) 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:909) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704) Caused by: org.greenrobot.greendao.DaoException: Could not init DAOConfig at org.greenrobot.greendao.internal.DaoConfig.(Unknown Source) at org.greenrobot.greendao.AbstractDaoMaster.registerDaoClass(Unknown Source) at my.app.package.database.model.DaoMaster.(Unknown Source) at my.app.package.database.model.DaoMaster.(Unknown Source) at my.app.package.ZamgApplication.onCreate(Unknown Source) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4566) at android.app.ActivityThread.access$1500(ActivityThread.java:148) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5272) 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:909) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704) Caused by: java.lang.ArrayIndexOutOfBoundsException: length=5; index=6 at org.greenrobot.greendao.internal.DaoConfig.reflectProperties(Unknown Source) at org.greenrobot.greendao.internal.DaoConfig.(Unknown Source) at org.greenrobot.greendao.AbstractDaoMaster.registerDaoClass(Unknown Source) at my.app.package.database.model.DaoMaster.(Unknown Source) at my.app.package.database.model.DaoMaster.(Unknown Source) at my.app.package.ZamgApplication.onCreate(Unknown Source) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4566) at android.app.ActivityThread.access$1500(ActivityThread.java:148) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5272) 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:909) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)
在没有 ProGuard 的情况下编译应用程序时,一切正常。
我在这里缺少任何配置吗?我找不到任何关于谷歌的东西......
答:
似乎指令:
-keep class org.greenrobot.greendao.**
未应用。正如您在日志中看到的,这些行如下:
at org.greenrobot.a.c.a.a(Unknown Source)
at org.greenrobot.a.c.a.(Unknown Source)
at org.greenrobot.a.b.a(Unknown Source)
显示下面的类正在被混淆,而您的 ProGuard 指令正在告诉(或应该告诉)ProGuard 保持它们不变。要解决此问题,请确保在 Android 配置部分中正确引用了定义此问题的 ProGuard 规则文件:org.greenrobot.greendao
proguardFiles
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
并且您的发布配置使用相同的文件。proguard-rules.pro
评论
你是项目中的类吗?
如果没有,你像这样放你的类
的包keep
Entity
keep
Entity
-keep class com.xxx.xxx.model.* {*;}
评论
你可以试试这个
-dontwarn org.greenrobot.greendao.**
-keepclassmembers class * extends de.greenrobot.dao.AbstractDao {
}
-keep class **$Properties
使用更新版本
apply plugin: 'org.greenrobot.greendao'
compile 'org.greenrobot:greendao:3.2.0'
此处和此处以及 StackOverflow 上列出了相同的问题
我遇到了同样的问题
似乎只能保证保留类本身,但其成员仍可能被删除-keep class
在我的例子中,一个类的一些静态最终字段被删除,这最终导致索引越界异常CustomDao$Properties
取代
-keep class **$Properties
跟
-keep class **$Properties { *; }
解决了我的问题
评论
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/**
* DAO for table "addresses".
*/
public class DbAddressDao extends AbstractDao<DbAddress, Long> {
public static final String TABLENAME = "addresses";
/**
* Properties of entity DbAddress.<br/>
* Can be used for QueryBuilder and for referencing column names.
*/
public static class Properties {
public final static Property Id = new Property(0, long.class, "id", true, "_id");
public final static Property AddressLine = new Property(3, String.class, "addressLine", false, "ADDRESS_LINE");
}
如果你查看 GreenDao 库自动生成的 Dao 类 您可以注意到,它创建了一个名为 Properties 的内部类,其中包含数据库表中的每个字段,如上例所示。
你注意这些字段,你会注意到它们没有被用于代码的任何部分,因为 GreenDao 通过 DaoConfig 类使用反射来获取这些字段。请参阅 DaoConfig 中的 reflectProperties 方法。
问题是,当您启用 Proguard 时,它会理解属性中的所有这些字段都没有在任何地方使用,因此 Proguard 会将其删除。
因此,为避免这种情况发生,请将以下行添加到您的 Proguard 文件中:
-keep class **$Properties
-keepclassmembers class **$Properties {
public static <fields>;
}
这应该可以解决问题。
在下面添加的行 proguard-rules.pro 为我解决了这个问题。
-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {
public static java.lang.String TABLENAME;
}
-keep class **$Properties
谢谢@mgpx
评论