Подтвердить что ты не робот

Только использование Proguard: не удалось инициализировать 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 все работает нормально.

Мне не хватает какой-либо конфигурации здесь? я не мог найти ничего с Google в этом...

4b9b3361

Ответ 1

Вы keep класс Entity в своем проекте?
Если нет, keep пакет, который вы поместите в класс Entity как это
-keep class com.xxx.xxx.model.* {*;}

Ответ 2

Я столкнулся с той же проблемой

Кажется, что -keep class гарантирует только сохранение самого класса, но его члены могут быть удалены

В моем случае некоторые статические конечные поля класса CustomDao$Properties удаляются, что в итоге приводит к исключению индекса за пределами границ.

замена

-keep class **$Properties

с

-keep class **$Properties { *; }

решил мою проблему

Ответ 3

Кажется, что инструкция:

-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 оставить их неизменными. Чтобы исправить это, убедитесь, что файл правил ProGuard, где это определено, корректно ссылается в разделе proguardFiles вашей конфигурации Android:

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

и что ваша версия конфигурации использует тот же файл proguard-rules.pro.

Ответ 4

Вы можете попробовать это

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

Те же проблемы перечислены Здесь и здесь и на fooobar.com/questions/419363/...

Ответ 5

// 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 вы можете заметить, что он создает внутренний класс с именем Properties с каждым вашим полем в таблице базы данных, как в примере выше.

Если вы обратите внимание на эти поля, вы можете заметить, что они не используются ни в одной части кода, потому что GreenDao использует отражение через класс DaoConfig для получения этих полей. См. метод отражать свойства в DaoConfig.

Проблема в том, что когда вы включаете Proguard, он понимает, что все эти поля внутри Properties нигде не используются, поэтому Proguard удаляет его.

Поэтому, чтобы этого не случилось, добавьте следующие строки в ваш файл Proguard:

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

Это должно решить проблему.