Error on using proguard with Android Facebook sdk 3.0

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-27 23:15:15

问题


Warning: I removed a lot of "old text" to keep the question more clean. Just check the history if needed.

I'm using proguard to both shrink and obfuscate an app that uses the facebook sdk 3.0 (I'm using the sdk-version-3.0.2.b tag). I'm not using a JAR file. Instead, I imported the sdk inside my workspace, as taught by the documentation.

At a certain point in the execution, the app loads a PlacePickerFragment to let the user choose the place where he is. To code this, I follow exactly the Scrumptious tutorial. When I generate the debug apk without using proguard everything works as expected. But when I generate the signed apk using proguard, it crashes when the PlacePickerFragment loads nearby places with the following trace:

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)

Trying to avoid this error, I kept all facebook classes untouched, but didn't work. My current proguard-project.txt file:

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

My current projet.properties file (excerpt):

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

As you can see, my proguard configuration is a "specialization" of this file.

If I put -dontobfuscate in proguard-project.txt file, it will work. But what I don't understand is that the keep class com.facebook.** should already prevent classes related to facebook to be obfuscated. Which suggests that the problem is not directly related to the facebook classes.

The excerpt of code that throws com.facebook.FacebookGraphObjectException is:

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());
        }
    // [...]
}

Clearly, expectedTypeAsParameterizedType is null in release build. But in both builds (debug and release) expectedType is a com.facebook.model.GraphObjectList interface. Unfortunately, I don't understand almost nothing about Java reflection concepts.

How can I fix this problem?


回答1:


This will solve your problem, i hope:

And the winner is .....

-keepattributes Signature

From Proguard Homepage:

The "Signature" attribute is required to be able to access generic types when compiling in JDK 5.0 and higher.




回答2:


if you want to proguard Facebook, the config below is working for me

#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();
}



回答3:


This may work (untested)

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



回答4:


Try

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

The reason being, is that when specifying private, public, protected you're still opening up default (package private) access to obfuscation.



来源:https://stackoverflow.com/questions/13538070/error-on-using-proguard-with-android-facebook-sdk-3-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!