在Android上使用OrmLite和Proguard

23

我应该如何在Android中使用proguard和ormlite库?

尝试这样做:

-keep class com.j256.**
-keepclassmembers class com.j256.**
-keep enum com.j256.**
-keepclassmembers enum com.j256.**
-keep interface com.j256.**
-keepclassmembers interface com.j256.**

但我得到了以下错误信息:

03-23 20:23:54.518: E/AndroidRuntime(3032): java.lang.RuntimeException: Unable to start activity ComponentInfo{cz.eman.android.cepro/cz.eman.android.cepro.activity.StationsOverviewActivity}: java.lang.IllegalStateException: Could not find constructor that takes a Context argument for helper class class kb

我还尝试添加了以下内容:

-keepclassmembers class * { public <init>(android.content.​Context); }

但我得到了另一个类成员的错误。


1
我的回答有帮到你吗?如果有的话,请接受它。如果没有,请提供你自己的答案。 - Gray
1
请在找到答案后发布答案或将答案标记为正确,这可以帮助其他人找到答案。 - Nixit Patel
你最终是如何解决这个问题的? - Frank
4
我通过执行以下所有步骤(来自Gray和German的答案)进行了修复,之后我还必须像这样将所有我的数据库内容对象(带有一个或多个@DatabaseField)添加到我的ProGuard配置中:-keep class com.myapp.model.** -keepclassmembers class com.myapp.model.** { *; }。 - Frank
1
弗兰克,你救了我的命啊! - baboo
8个回答

41

非常感谢像这样的帖子,它们帮助我们逐步进步。

在我尝试了最后一个解决方案而没有成功之后,我想出了另一种解决方案:

# OrmLite uses reflection
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }
我希望它能对某人有所帮助。

对我来说还不够.... 它会抛出类似这样的错误: 字段 FieldType:name=b,class=Location 的类 java.lang.String 对于数据持久化器 com.j256.ormlite.field.types.DateLongType@20f95c38 是无效的。 - Jacek Kwiecień
仅保留ORM帮助程序类的构造函数:-keepclassmembers class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper { public (android.content.Context); }保留具有DatabaseTable的数据库类:-keep @com.j256.ormlite.field.* public class *保留数据库类中的DB字段:-keepclassmembers class * { @com.j256.ormlite.field. *; } - Sergii.PSP

20

被采纳的答案对我的情况不够,所以我进行了加强并得出了以下结果:

# OrmLite uses reflection
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }

# Keep the helper class and its constructor
-keep class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper
-keepclassmembers class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper {
  public <init>(android.content.Context);
}

# Keep the annotations
-keepattributes *Annotation*

# Keep all model classes that are used by OrmLite
# Also keep their field names and the constructor
-keep @com.j256.ormlite.table.DatabaseTable class * {
    @com.j256.ormlite.field.DatabaseField <fields>;
    @com.j256.ormlite.field.ForeignCollectionField <fields>;
    # Add the ormlite field annotations that your model uses here
    <init>();
}

经过大量搜索,这是唯一对我有效的答案。我遇到了“IllegalArgumentException: Foreign field class x does not have id field”,我认为最后一个keep块解决了它。谢谢。 - bradkratky
另外一行修复了我在尝试创建签名APK时的错误:-dontwarn com.j256.ormlite.android.**,因为最新的'com.j256.ormlite:ormlite-android:5.0'中,com.j256.ormlite.android.OrmliteTransactionalProcessor扩展了Processor。 - Zbarcea Christian
6
为了适应ORMLite 5.0版本,我需要添加以下内容: -dontwarn com.j256.ormlite.android.** -dontwarn com.j256.ormlite.logger.** -dontwarn com.j256.ormlite.misc.** 这些内容的作用是禁止警告信息出现,以确保程序的正确运行。 - Diederik
这是唯一对我有效的方法,但是除此之外,我还必须将所有的com.j256.转换为com.j256(即去掉点),否则我会得到一个“未解决的类名”红色下划线(Android Studio 4.1.2)。 - Mitch

15

-keepclassmembers class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper { public <init>(android.content.Context); } - Miha_x64

3

对于上述配置的小细节 - 如果你正在尝试通过 ORMLite 序列化/反序列化 Joda 的 DateTime 对象,你可能也需要这个:

-keepclassmembers class **DateTime {
    <init>(long);
    long getMillis();
}

由于ORMLite的DateTimeType是通过反射完成所有操作的。


谢谢Thomas,很有趣,我在这里找到了我正在寻找的答案 :) - Tino
呵呵 :) 而且我在这里也没有过于活跃。 - Thomas Keller

1

除了反射所必需的默认内容:

# OrmLite uses reflection
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }

我需要保留所有实体类:

-keep class com.example.db.Entities.** { *; }

否则实体类将被剥离。 我使用预定义的数据库(之前生成的)。
有更简单/更好的混淆方式吗?也许我保留了太多类?

0
在我的情况下,这个做法起了作用:
-keepattributes SourceFile,LineNumberTable,Signature,InnerClasses,*Annotation*

并且

-keepclassmembers class * {public <init>(android.content.Context);}
-keep class com.j256.** { *; }

通过混淆和优化。


0

最新版本OrmLite 5的一个小添加。

您可能想要添加以下行来隐藏一些新警告:

-dontwarn com.j256.ormlite.android.**
-dontwarn com.j256.ormlite.logger.**
-dontwarn com.j256.ormlite.misc.**

警告信息如下:

警告:com.j256.ormlite.android.OrmliteTransactionalProcessor: 找不到引用的类javax.lang.model.SourceVersion

警告:com.j256.ormlite.logger.Slf4jLoggingLog: 找不到引用的类org.slf4j.LoggerFactory

警告:com.j256.ormlite.misc.JavaxPersistenceImpl: 找不到引用的类javax.persistence.Column


-2

我想出了这样的解决方案(也许对某些人有用)。

proguard.cfg进行了如下更改:

  • 添加了-dontobfuscate选项

  • -optimization选项附加了,!code/allocation/variable

使用这种配置的APK文件大小从580 kB减小到250 kB。

尽管如此,没有执行混淆。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接