仅使用Proguard:无法初始化DaoConfig => ArrayIndexOutOfBoundsException异常

时间:2017-02-03 11:53:59

标签: android android-proguard greendao greendao-generator

我使用以下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的情况下编译应用程序时,一切正常。

我在这里错过了任何配置吗?我找不到与谷歌有关的任何事情......

5 个答案:

答案 0 :(得分:9)

您是否keep项目中的Entity课程? 如果没有,keep您放入Entity班级的套餐 像这样 -keep class com.xxx.xxx.model.* {*;}

答案 1 :(得分:2)

似乎是指令:

-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保持不变时,org.greenrobot.greendao下的类被混淆了。要解决此问题,请确保在Android配置的proguardFiles部分中正确引用了定义此文件的ProGuard规则文件:

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

并且您的发布配置使用相同的proguard-rules.pro文件。

答案 2 :(得分:1)

你可以试试这个

-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'

列出Here here以及StackOverflow

的相同问题

答案 3 :(得分:0)

我遇到了同样的问题

似乎-keep class仅保证保留该类本身,但仍可以删除其成员

在我的情况下,CustomDao$Properties类的某些静态final字段被删除,最终导致索引超出范围异常

替换

-keep class **$Properties

-keep class **$Properties { *; }

解决了我的问题

答案 4 :(得分:0)

// 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类使用反射来获取这些字段。参见将方法reflectProperties导入DaoConfig。

问题是当您启用Proguard时,它了解到Properties内的所有这些字段均未在任何地方使用,因此Proguard会将其删除。

因此,为避免发生这种情况,请将以下行添加到Proguard文件中:

-keep class **$Properties
-keepclassmembers class **$Properties {
    public static <fields>;
}

这应该可以解决问题。