在 Android Facebook sdk 3.0 中使用 proguard 时出错
Posted
技术标签:
【中文标题】在 Android Facebook sdk 3.0 中使用 proguard 时出错【英文标题】:Error on using proguard with Android Facebook sdk 3.0 【发布时间】:2012-11-12 08:22:45 【问题描述】:警告:我删除了很多“旧文本”以保持问题更清晰。如果需要,只需检查历史记录。
我正在使用proguard
来缩小和混淆使用facebook sdk 3.0 的应用程序(我正在使用sdk-version-3.0.2.b tag)。我没有使用 JAR 文件。相反,我按照documentation 的教导将 sdk 导入到我的工作区中。
在执行的某个时刻,应用会加载一个PlacePickerFragment,让用户选择他所在的位置。为了编写代码,我完全遵循Scrumptious tutorial。 当我在不使用proguard
的情况下生成调试 apk 时,一切都按预期工作。 但是当我使用 proguard
生成签名 apk 时,当 PlacePickerFragment 加载具有以下跟踪的附近地点时,它会崩溃: p>
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.FacebookGraphObjectException
的excerpt 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 反射概念几乎一无所知。
我该如何解决这个问题?
【问题讨论】:
【参考方案1】:这将解决您的问题,我希望:
获胜者是.....
-keepattributes Signature
来自 Proguard 主页:
“签名”属性是访问通用属性所必需的 在 JDK 5.0 及更高版本中编译时的类型。
【讨论】:
【参考方案2】:如果你想保护 Facebook,下面的配置对我有用
#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();
【讨论】:
只有这个完整的解决方案对我有用-keepattributes Signature
没有解决问题【参考方案3】:
这可能有效(未经测试)
-keep class com.facebook.** *;
【讨论】:
【参考方案4】:试试
-keep class com.facebook.**
*;
原因是,当指定私有、公共、受保护时,您仍然会打开对混淆的默认(包私有)访问权限。
【讨论】:
以上是关于在 Android Facebook sdk 3.0 中使用 proguard 时出错的主要内容,如果未能解决你的问题,请参考以下文章
使用 Facebook-Android SDK 3.0 正确请求发布权限
Android Facebook SDK 3.23.0 - AndroidTV 上的 FB 登录
Android 如何在新的 sdk 3.0 中与 Facebook Open Graph 共享数据?
在 Android Facebook sdk 3.0 中使用 proguard 时出错
Android Studio 中的 Facebook SDK 4 ExceptionInitializeError Login v2.3