简体   繁体   English

Joda-Time库在启用Proguard的Android 5上不起作用

[英]Joda-Time library is not working on Android 5 with Proguard enabled

This problem is only occurring in Android 5. The app crashes write at the point and i create a new DateTime object like: 仅在Android 5中会出现此问题。该应用程序此时崩溃写入,并且我创建了一个新的DateTime对象,例如:

mStartTime = new DateTime(DateTimeZone.getDefault());

Crash Report is: 崩溃报告是:

java.lang.AbstractMethodError: abstract method "long boq.f()"
   at org.joda.time.chrono.BasicYearDateTimeField.(BasicYearDateTimeField.java:46)
   at org.joda.time.chrono.BasicChronology.assemble(BasicChronology.java:273)
   at org.joda.time.chrono.GregorianChronology.assemble(GregorianChronology.java:197)
   at org.joda.time.chrono.AssembledChronology.setFields(AssembledChronology.java:323)
   at org.joda.time.chrono.AssembledChronology.(AssembledChronology.java:102)
   at org.joda.time.chrono.BasicChronology.(BasicChronology.java:131)
   at org.joda.time.chrono.BasicGJChronology.(BasicGJChronology.java:75)
   at org.joda.time.chrono.GregorianChronology.(GregorianChronology.java:153)
   at org.joda.time.chrono.GregorianChronology.getInstance(GregorianChronology.java:133)
   at org.joda.time.chrono.GregorianChronology.getInstance(GregorianChronology.java:99)
   at org.joda.time.chrono.GregorianChronology.(GregorianChronology.java:70)
   at org.joda.time.chrono.GregorianChronology.getInstanceUTC(GregorianChronology.java:80)
   at org.joda.time.chrono.ISOChronology.(ISOChronology.java:59)
   at org.joda.time.base.BaseDateTime.(BaseDateTime.java:73)
   at org.joda.time.DateTime.(DateTime.java:184)
   at com.znapo.photo_sharer.asynctasks.GetAllSessionTask.onPostExecute(GetAllSessionTask.java:149)
   at com.znapo.photo_sharer.asynctasks.GetAllSessionTask.onPostExecute(GetAllSessionTask.java:1)
   at android.os.AsyncTask.finish(AsyncTask.java:636)
   at android.os.AsyncTask.access$500(AsyncTask.java:177)
   at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:653)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:135)
   at android.app.ActivityThread.main(ActivityThread.java:5254)
   at java.lang.reflect.Method.invoke(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:372)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

My Complete Proguard Configuration file is: 我的完整Proguard配置文件是:

-dontwarn org.apache.**
-dontwarn com.google.android.**
-dontskipnonpubliclibraryclassmembers

##---------------Begin: proguard configuration common for all Android apps ----------
-optimizationpasses 5
-dontpreverify
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-allowaccessmodification
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable
-repackageclasses ''

-keep public class * extends android.app.Activity
#-keep public class * extends android.support.v7.app.ActionBarActivity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-dontnote com.android.vending.licensing.ILicensingService

# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

# Preserve static fields of inner classes of R classes that might be accessed
# through introspection.
-keepclassmembers class **.R$* {
  public static <fields>;
}

# Preserve the special static methods that are required in all enumeration classes.
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}


-keep public class * {
    public protected *;
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
##---------------End: proguard configuration common for all Android apps ----------

#for support library
-keep class android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }
-keep class android.support.v4.** { *; }
-keep class android.support.v13.** { *; }
-keep interface android.support.v4.** { *; }
-keep interface android.support.v13.** { *; }

#for retracing obfuscated stack traces
-keepattributes SourceFile,LineNumberTable

##---------------Begin: proguard configuration for Gson  ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
-keep class com.tweetstudio.tweet_studio_app.dto.** { *; }

##---------------End: proguard configuration for Gson  ----------


##--------For Google Play services-------------##

-keep class * extends java.util.ListResourceBundle {
    protected Object[][] getContents();
}

-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
    public static final *** NULL;
}

-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
    @com.google.android.gms.common.annotation.KeepName *;
}

-keepnames class * implements android.os.Parcelable {
    public static final ** CREATOR;
}

##---------- End: proguard configuration for google play ---------------

##---------- proguard configuration for joda-time ---------------

-dontwarn org.joda.convert.**
-dontwarn javax.xml.bind.DatatypeConverter

Following jars are added to the build path for Joda-Time: 以下jar被添加到Joda-Time的构建路径中:

joda-time-2.7.jar
joda-convert-1.7.jar
joda-time-2.7-javadoc.jar

After converting the joda-convert-2.7.jar to zip and exploring the line 46 of BasicYearDateTimeField i am seeing this line of code: joda-convert-2.7.jarzip并浏览BasicYearDateTimeField的第46行之后,我看到了以下代码行:

super(DateTimeFieldType.year(), chronology.getAverageMillisPerYear());

You can add the line:- 您可以添加以下行:

-keep class org.joda.** { *; }

to your proguard config. 到您的proguard配置。 This will prevent the code from joda library to be removed. 这样可以防止从joda库中删除代码。 Adding this line increased the apk size by 2.8 KB only for me. 添加此行仅对我来说将apk大小增加了2.8 KB。

您可以使用此github Joda-Time Library Git Hub Joda Time

Maybe a peek at some documentation will shed some light: 也许看一些文档会有所启发:

AbstractMethodError AbstractMethodError

Thrown when an application tries to call an abstract method. 当应用程序尝试调用抽象方法时抛出。 Normally, this error is caught by the compiler; 通常,此错误由编译器捕获; this error can only occur at run time if the definition of some class has incompatibly changed since the currently executing method was last compiled. 如果自上次编译当前执行的方法以来某个类的定义发生了不兼容的更改,则仅在运行时会发生此错误。

Something promised that "long boq.f()" would be implemented and it lied. 有人承诺“ long boq.f()”将被实施,并且说谎。 That should only be possible at run time if something that should have been recompiled wasn't recompiled. 只有在未重新编译本应重新编译的内容的情况下,才应在运行时这样做。

I would write a simple stand alone program that used joda-time and new DateTime(DateTimeZone.getDefault()); 我将编写一个简单的独立程序,该程序使用joda-time和new DateTime(DateTimeZone.getDefault()); see if the problem was easy to reproduce. 看看问题是否容易重现。 If it is you've isolated the problem to that version of joda-time. 如果是这样,您已经将问题隔离到该版本的joda-time。 See if rolling back to an older one makes the problem go away. 查看是否回滚到较旧版本可以解决问题。

You could also just recomiple joda-time and anything that talks to joda-time. 您也可以将joda-time以及任何与joda-time对话的内容重新组合。 Doing this should at the very least turn this run time error into a compile time error. 这样做至少应该将运行时错误转换为编译时错误。 That should make it easy to see what is wrong. 那应该很容易看出问题所在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM