2012-11-24 88 views
17

Warning:我刪除了很多「舊文本」以使問題更加清晰。如果需要,請檢查歷史記錄。在Android上使用proguard的錯誤Facebook Facebook sdk 3.0

我正在使用proguard來縮小和混淆使用facebook sdk 3.0(我正在使用sdk-version-3.0.2.b tag)的應用程序。我沒有使用JAR文件。相反,我在工作區內導入了sdk,如documentation所教導的。

在執行過程中的某個點,應用程序會加載一個PlacePickerFragment以讓用戶選擇他所在的位置。爲了編碼,我遵循Scrumptious tutorial當我生成調試apk而不使用proguard一切都按預期工作。但是,當我生成使用proguard簽署的APK,它崩潰時PlacePickerFragment負載附近的地方有以下跟蹤:

E/AndroidRuntime(27472): FATAL EXCEPTION: main 
E/AndroidRuntime(27472): com.facebook.FacebookGraphObjectException: can't infer generic type of: interface com.facebook.model.GraphObjectList 
E/AndroidRuntime(27472): at com.facebook.model.GraphObject$Factory.coerceValueToExpectedType(Unknown Source) 
E/AndroidRuntime(27472): at com.facebook.model.GraphObject$Factory$GraphObjectProxy.proxyGraphObjectGettersAndSetters(Unknown Source) 
E/AndroidRuntime(27472): at com.facebook.model.GraphObject$Factory$GraphObjectProxy.invoke(Unknown Source) 
E/AndroidRuntime(27472): at com.facebook.widget.$Proxy2.getData(Native Method) 
E/AndroidRuntime(27472): at com.facebook.widget.GraphObjectPagingLoader.addResults(Unknown Source) 
E/AndroidRuntime(27472): at com.facebook.widget.GraphObjectPagingLoader.requestCompleted(Unknown Source) 
E/AndroidRuntime(27472): at com.facebook.widget.GraphObjectPagingLoader.access$1(Unknown Source) 
E/AndroidRuntime(27472): at com.facebook.widget.GraphObjectPagingLoader$2.onCompleted(Unknown Source) 
E/AndroidRuntime(27472): at com.facebook.Request$4.run(Unknown Source) 
E/AndroidRuntime(27472): at android.os.Handler.handleCallback(Handler.java:587) 
E/AndroidRuntime(27472): at android.os.Handler.dispatchMessage(Handler.java:92) 
E/AndroidRuntime(27472): at android.os.Looper.loop(Looper.java:130) 
E/AndroidRuntime(27472): at android.app.ActivityThread.main(ActivityThread.java:3687) 
E/AndroidRuntime(27472): at java.lang.reflect.Method.invokeNative(Native Method) 
E/AndroidRuntime(27472): at java.lang.reflect.Method.invoke(Method.java:507) 
E/AndroidRuntime(27472): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
E/AndroidRuntime(27472): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625) 
E/AndroidRuntime(27472): at dalvik.system.NativeStart.main(Native Method) 

試圖避免這種錯誤,我保存了所有的Facebook類不變,但沒有奏效。我現在proguard-project.txt文件:

-keep class com.facebook.** { 
    *; 
} 

我現在projet.properties文件(節選):

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 

正如你看到的,我proguard配置是的this file 「專業化」。

如果我把-dontobfuscate放在proguard-project.txt文件中,它就會起作用。但我不明白的是,keep class com.facebook.**應該已經阻止與Facebook相關的類被混淆。這表明該問題與facebook類沒有直接關係。

的拋出com.facebook.FacebookGraphObjectExceptionexcerpt of code是:

static <U> U coerceValueToExpectedType(Object value, Class<U> expectedType, 
     ParameterizedType expectedTypeAsParameterizedType) { 

    // [...] 

    } else if (Iterable.class.equals(expectedType) || Collection.class.equals(expectedType) 
     || List.class.equals(expectedType) || GraphObjectList.class.equals(expectedType)) { 
     if (expectedTypeAsParameterizedType == null) { 
      throw new FacebookGraphObjectException("can't infer generic type of: " + expectedType.toString()); 
     } 
    // [...] 
} 

顯然,expectedTypeAsParameterizedType是在發佈版本null。但在兩個版本(調試和發佈)中,expectedType都是com.facebook.model.GraphObjectList接口。不幸的是,我幾乎不瞭解Java反射概念。

我該如何解決這個問題?

回答

30

這將解決你的問題,我希望:

與獲獎者是.....

-keepattributes Signature 

從Proguard的主頁:

「簽名」 屬性是必需的JDK 5.0和更高的編譯時能夠訪問通用 類型。

+0

非常感謝! – borges

0

這可能工作(未經測試)

-keep class com.facebook.** { *; } 
+0

它的工作部分,請看到我的編輯。 – borges

0

嘗試

-keep class com.facebook.** { 
    *; 
} 

其原因是,指定是私人的,公共的,保護你還開闢默認(包私有)訪問時混淆。

+0

它部分工作,請參閱我的編輯。 – borges

15

如果你想ProGuard的臉譜,下面的配置爲我工作

#modify for Facebook 
-keepattributes Signature 
-keep class com.facebook.model.** { *; } 

-keepnames class * implements java.io.Serializable 
-keepclassmembers class * implements java.io.Serializable { 
    static final long serialVersionUID; 
    private static final java.io.ObjectStreamField[] serialPersistentFields; 
    !static !transient <fields>; 
    private void writeObject(java.io.ObjectOutputStream); 
    private void readObject(java.io.ObjectInputStream); 
    java.lang.Object writeReplace(); 
    java.lang.Object readResolve(); 
} 
+0

只有這個完整的解決方案爲我工作'-keepattributes Signature'沒有解決問題 –