如何使用ProGuard使org.apache.http.legacy与Azure移动服务配合工作?

9
问题:
我正在使用Android移动服务,它依赖于androidhttpclient。
引用org.apache.http.legacy可以解决所有问题,应用程序运行得很好。但是,启用了proguard后,我仍然遇到问题。
问题分为两种情况。如果我保持导出复选框选中(在jave构建路径中),我会像预期的那样收到'Stub!'异常(请参见下面的讨论)(请参见屏幕截图,其中显示了我所说的复选框)。

enter image description here

类型为“Stub!”的运行时崩溃:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.stuffd/com.stuffd.MainActivity}: java.lang.RuntimeException: Stub!
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2345)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2405)
       at android.app.ActivityThread.access$800(ActivityThread.java:149)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1324)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:211)
       at android.app.ActivityThread.main(ActivityThread.java:5317)
       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:1016)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
Caused by: java.lang.RuntimeException: Stub!
   at org.apache.http.message.AbstractHttpMessage.(AbstractHttpMessage.java:7)
   at org.apache.http.client.methods.HttpRequestBase.(HttpRequestBase.java:7)
   at org.apache.http.client.methods.HttpGet.(HttpGet.java:8)
   at com.microsoft.windowsazure.mobileservices.table.MobileServiceJsonTable.executeGetRecords(MobileServiceJsonTable.java:952)
   at com.microsoft.windowsazure.mobileservices.table.MobileServiceJsonTable.executeUrlQuery(MobileServiceJsonTable.java:183)
   at com.microsoft.windowsazure.mobileservices.table.MobileServiceJsonTable.execute(MobileServiceJsonTable.java:160)
   at com.microsoft.windowsazure.mobileservices.table.MobileServiceTable.execute(MobileServiceTable.java:158)
   at com.microsoft.windowsazure.mobileservices.table.MobileServiceTable.execute(MobileServiceTable.java:249)
   at com.microsoft.windowsazure.mobileservices.table.query.ExecutableQuery.execute(ExecutableQuery.java:101)

如果我不勾选复选框(如下面的讨论所建议),则会出现AbstractMethodError异常。
java.lang.RuntimeException: An error occured while executing doInBackground()
       at android.os.AsyncTask$3.done(AsyncTask.java:300)
       at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
       at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
       at java.util.concurrent.FutureTask.run(FutureTask.java:242)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:811)
Caused by: java.lang.AbstractMethodError: abstract method "java.lang.String org.apache.http.client.methods.HttpRequestBase.getMethod()"
       at android.net.http.AndroidHttpClient.getMethod(AndroidHttpClient.java:283)
       at android.net.http.AndroidHttpClient.execute(AndroidHttpClient.java:301)

使用的Proguard配置:

-dontwarn org.apache.http.**
-dontwarn android.net.http.**
-dontwarn com.microsoft.windowsazure.mobileservices.**

是否有其他人遇到过这个问题并已经解决了?


不确定您使用的构建工具是什么,但一般来说,不要将存根库链接到您的项目中。只需将其作为提供的依赖项进行构建即可。 - Kevin Krumwiede
@KevinKrumwiede,这是一个问题,org.apache.http.legacy不应该是一个存根库...我找到了另一个链接表明这是一个类路径排序问题(https://groups.google.com/forum/#!topic/robolectric/guRK1b8aEIQ),但移动东西似乎没有帮助。 - rothschild86
2
是的,它应该是一个存根库。整个Android SDK都是一个存根库。Apache HTTP仍然存在于API 23设备上。它只是从主存根库中移出,以进一步阻止其使用。 - Kevin Krumwiede
1
你是否在 build.gradle 中的 android { ... } 部分中添加了 useLibrary 'org.apache.http.legacy' (比如在 buildToolsVersion 下面的某个位置)? - fattire
1
存根不会被替换。应用程序应该引用存根类和方法,但不包括它们在apk中。如果实现在运行时不存在,则会出现“NoClassDefFoundError”。看到“java.lang.RuntimeException: Stub!”表示子库已编译到apk中。 - Kevin Krumwiede
显示剩余3条评论
2个回答

12

我正在使用以下代码,以便让操作系统在运行时正确替换存根方法。

-keep class org.apache.http.** { *; }
-keep class org.apache.commons.codec.** { *; }
-keep class org.apache.commons.logging.** { *; }
-keep class android.net.compatibility.** { *; }
-keep class android.net.http.** { *; }
-dontwarn org.apache.http.**
-dontwarn android.webkit.**

这是由org.apache.http.legacy.jar提供的所有存根包。


感谢您的贡献。在我的情况下仍然是一个存根/抽象运行时异常... - rothschild86
这个回答需要更多的关注 - 它是唯一一个让我使用Eclipse和Proguard编译SDK 23的解决方案。 - mike47
1
@ mikejeep 这是目前为止唯一的答案 :) 顺便说一句,尽管我的编译了,但我开始出现运行时错误... - rothschild86
@rothschild86 在SO上有很多类似的问题..但只有这一个对我起了作用。其他所有的都导致了运行时错误。 - mike47
@mikejeep 哦,我明白了 :) - rothschild86
我可以确认异常出现在compileSdkVersion 23useLibrary 'org.apache.http.legacy',但是无法找到解决方法。Gradle构建挂起并要求我先修复警告,警告是“存在1个未解析的库类成员引用”。我尝试了你的答案,但无法让Proguard满意:( - yorkw

0

你说得对,不导出旧版的apache库。但是它必须位于libs文件夹之外,并添加到构建路径(在使用Eclipse时)。否则,它仍会随着你的Android Private Libraries一起被导出。

我在自己的通信类中使用了GMS、Volley和AndroidHttpClient。以下是我需要添加到proguard设置中的内容:

-dontwarn org.apache.http.**
-dontwarn com.google.android.gms.**
-dontwarn com.android.volley.toolbox.**
-dontwarn com.myapp.communication.**
-keep class com.google.android.gms.** { *; }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接