21

我正在使用以下 ProGuard 规则:

-keepclassmembers 类 * 扩展 org.greenrobot.greendao.AbstractDao { *; }
-保持类**$属性

-保留类 org.greenrobot.greendao.**
-keepclassmembers 类 org.greenrobot.greendao.** { *; }

# 如果不使用 SQLCipher:
-dontwarn org.greenrobot.greendao.database.**

# 如果你不使用 RxJava:
-dontwarn rx.**

启动应用程序时,我收到以下崩溃日志:

java.lang.RuntimeException:无法创建应用程序 my.app.package.MyApplication:org.greenrobot.greendao.DaoException:无法初始化 DAOConfig
   在 android.app.ActivityThread.handleBindApplication(ActivityThread.java:4569)
   在 android.app.ActivityThread.access$1500(ActivityThread.java:148)
   在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
   在 android.os.Handler.dispatchMessage(Handler.java:102)
   在 android.os.Looper.loop(Looper.java:135)
   在 android.app.ActivityThread.main(ActivityThread.java:5272)
   在 java.lang.reflect.Method.invoke(本机方法)
   在 java.lang.reflect.Method.invoke(Method.java:372)
   在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)
   在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)
原因:org.greenrobot.greendao.DaoException:无法初始化 DAOConfig
   在 org.greenrobot.greendao.internal.DaoConfig.(未知来源)
   在 org.greenrobot.greendao.AbstractDaoMaster.registerDaoClass(未知来源)
   在 my.app.package.database.model.DaoMaster.(​​未知来源)
   在 my.app.package.database.model.DaoMaster.(​​未知来源)
   在 my.app.package.ZamgApplication.onCreate(未知来源)
   在 android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011)
   在 android.app.ActivityThread.handleBindApplication(ActivityThread.java:4566)
   在 android.app.ActivityThread.access$1500(ActivityThread.java:148) 
   在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
   在 android.os.Handler.dispatchMessage(Handler.java:102) 
   在 android.os.Looper.loop(Looper.java:135) 
   在 android.app.ActivityThread.main(ActivityThread.java:5272) 
   在 java.lang.reflect.Method.invoke(本机方法) 
   在 java.lang.reflect.Method.invoke(Method.java:372) 
   在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909) 
   在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704) 
引起:java.lang.ArrayIndexOutOfBoundsException: length=5; 索引=6
   在 org.greenrobot.greendao.internal.DaoConfig.reflectProperties(未知来源)
   在 org.greenrobot.greendao.internal.DaoConfig.(未知来源) 
   在 org.greenrobot.greendao.AbstractDaoMaster.registerDaoClass(未知来源) 
   在 my.app.package.database.model.DaoMaster.(​​未知来源) 
   在 my.app.package.database.model.DaoMaster.(​​未知来源) 
   在 my.app.package.ZamgApplication.onCreate(未知来源) 
   在 android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011) 
   在 android.app.ActivityThread.handleBindApplication(ActivityThread.java:4566) 
   在 android.app.ActivityThread.access$1500(ActivityThread.java:148) 
   在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
   在 android.os.Handler.dispatchMessage(Handler.java:102) 
   在 android.os.Looper.loop(Looper.java:135) 
   在 android.app.ActivityThread.main(ActivityThread.java:5272) 
   在 java.lang.reflect.Method.invoke(本机方法) 
   在 java.lang.reflect.Method.invoke(Method.java:372) 
   在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909) 
   在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704) 

在没有 ProGuard 的情况下编译应用程序时,一切正常。

我在这里缺少任何配置吗?我在谷歌上找不到任何东西......

4

6 回答 6

14

你是项目中keepEntity班级吗?
如果没有,keep你把你的Entity班级放在
这样的包
-keep class com.xxx.xxx.model.* {*;}

于 2017-02-15T02:55:18.827 回答
8

我遇到了同样的问题

似乎-keep class只保证类本身被保留,但它的成员仍有可能被删除

在我的情况下,一个类的一些静态最终字段CustomDao$Properties被删除,最终导致索引越界异常

更换

-keep class **$Properties

-keep class **$Properties { *; }

解决了我的问题

于 2019-06-25T08:56:02.537 回答
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) 

表明org.greenrobot.greendao当你的 ProGuard 指令告诉(或应该告诉)ProGuard 保持它们不变时,下面的类被混淆了。要解决此问题,请确保在proguardFiles您的 Android 配置部分中正确引用了定义此内容的 ProGuard 规则文件:

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

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

于 2017-02-06T17:01:39.400 回答
1
// 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>;
}

这应该可以解决问题。

于 2019-08-13T16:15:03.047 回答
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'

此处此处以及StackOverflow上列出的相同问题

于 2017-02-17T10:29:07.643 回答
0

在 proguard-rules.pro 下面添加的行为我解决了这个问题。

-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {
public static java.lang.String TABLENAME;
}
-keep class **$Properties

谢谢@mgpx

于 2021-10-28T15:06:24.723 回答