2015-04-03 20 views
1

此問題僅在安卓5.出現應用崩潰寫在點和我創建一個新DateTime對象,如:喬達時庫不工作在Android上5 Proguard的啓用

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

崩潰報告是:

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) 

我的完整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 

弗洛翼罐子被添加到構建路徑喬達時間:

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

轉換後的joda-convert-2.7.jarzip和探索BasicYearDateTimeField 46我看到這行代碼行:

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

「這個問題只發生在Android 5」,意味着它不會發生在...? – CandiedOrange 2015-04-03 05:38:25

+0

在運行Andriod 5以下操作系統的設備上可以,應用工作正常。 – 2015-04-03 05:39:29

+0

在Android 4.4.4和4.0.2上測試,即使啓用了proguard,該應用也能正常工作。 – 2015-04-03 05:44:44

回答

1

您可以添加一行: -

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

您的ProGuard配置。這會阻止joda庫中的代碼被刪除。添加此行增加了apk大小2.8 KB只爲我。

0

也許偷看一些文檔會提供一些線索:

AbstractMethodError

應用程序嘗試調用抽象方法時拋出。通常,這個錯誤被編譯器捕獲;此錯誤只能在運行時發生,如果某些類的定義自上次編譯當前執行的方法以來發生了不兼容的更改。

東西承諾「long boq.f()」會被執行並且說謊。如果應該重新編譯的東西沒有重新編譯,那應該只在運行時纔可能。

我會寫一個簡單的獨立程序,使用joda時間和new DateTime(DateTimeZone.getDefault());看看問題是否容易重現。如果是這樣,你已經將問題與該版本的喬達時間分開了。看看是否回滾到較舊的問題會導致問題消失。

您也可以重新編寫喬達時間和任何與喬達時間交談的內容。這樣做至少應該將運行時錯誤轉化爲編譯時錯誤。這應該很容易看出什麼是錯的。

+0

但是,那麼解決方案是什麼? – 2015-04-03 05:48:38

+0

重新編譯?無論如何,當我看着http://joda-time.sourceforge.net/xref/org/joda/time/chrono/BasicYearDateTimeField.html第46行只是'iChronology =年表;'所以我想我在找在錯誤的版本。你的版本在第46行上有什麼? – CandiedOrange 2015-04-03 05:52:23

+0

我的版本中'BasicYearDateTimeField'的第46行:'super(DateTimeFieldType.year(),年表。getAverageMillisPerYear());' – 2015-04-03 05:56:48