启用 proguard 后 java.lang.NoSuchMethodError Org/apache/http/util/ByteArrayBuffer
Posted
技术标签:
【中文标题】启用 proguard 后 java.lang.NoSuchMethodError Org/apache/http/util/ByteArrayBuffer【英文标题】:java.lang.NoSuchMethodError Lorg/apache/http/util/ByteArrayBuffer after enabling progurd 【发布时间】:2018-07-24 22:31:03 【问题描述】:我的应用程序正在崩溃,如下面的日志所示。
我使用这些代码已经有一段时间了,但现在它突然崩溃了。
只有在我启用 progurd 时应用程序才会崩溃。如果不启用 progurd,它就可以工作
java.lang.NoSuchMethodError: No virtual method g([BII)V in class Lorg/apache/http/util/ByteArrayBuffer; or its super classes (declaration of 'org.apache.http.util.ByteArrayBuffer' appears in /system/framework/org.apache.http.legacy.boot.jar)
at android_support.bee.a(AbstractMultipartForm.java:55)
at android_support.bee.<clinit>(AbstractMultipartForm.java:92)
at android_support.bem.Iu(MultipartEntityBuilder.java:192)
at android_support.bem.Iv(MultipartEntityBuilder.java:204)
at android_support.bcx.mo(BaseUploadHttpRequest.java:119)
at android_support.mp.b(HurlStack.java:245)
at android_support.mp.a(HurlStack.java:219)
at android_support.mp.a(HurlStack.java:97)
at android_support.mi.c(BasicNetwork.java:131)
at android_support.lz.processRequest(NetworkDispatcher.java:120)
at android_support.lz.run(NetworkDispatcher.java:87)
Profurd-规则
-overloadaggressively
-useuniqueclassmembernames
-dontwarn org.apache.http.**
#-keep interface modules.** *;
#Crashlytics
#-keepattributes *Annotation*
#-keepattributes SourceFile,LineNumberTable
#-keep class com.crashlytics.** *;
#-dontwarn com.crashlytics.**
#end crashlytics
-dontpreverify
-repackageclasses 'android_spt'
-allowaccessmodification
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keepattributes *Annotation*
-keep public class * extends android.app.Activity
-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.view.View
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
-keepclasseswithmembers class *
public <init>(android.content.Context, android.util.AttributeSet);
-keepclasseswithmembers class *
public <init>(android.content.Context, android.util.AttributeSet, int);
-keepclassmembers class * extends android.content.Context
public void *(android.view.View);
public void *(android.view.MenuItem);
-keepclassmembers class * implements android.os.Parcelable
static ** CREATOR;
-keepclassmembers class **.R$*
public static <fields>;
-keepclassmembers class *
@android.webkit.javascriptInterface <methods>;
这里是代码,我正在使用 volley 向服务器发送 Multipart 数据,应用程序在 mBuilder.build();
上崩溃
public class BaseUploadHttpRequest<T> extends Request<T>
private static final int TIMEOUT_RETRY_POLICY = 15000;
private static Map<String, String> mParams = new HashMap<String, String>();
private static Map<String, File> mFiles = new HashMap<String, File>();
private final Object deserializer;
private final Class<T> clazz;
private final Listener<T> listener;
private MultipartEntityBuilder mBuilder = MultipartEntityBuilder.create();
public BaseUploadHttpRequest(String url, Class<T> clazz, Map<String, String> params, Map<String, File> files, Listener<T> listener,
ErrorListener errorListener, Object deserializer)
super(Method.POST, url, errorListener);
setRetryPolicy(new DefaultRetryPolicy(
TIMEOUT_RETRY_POLICY,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
this.clazz = clazz;
this.listener = listener;
this.deserializer = deserializer;
mFiles.putAll(files);
//mHeader.putAll(appendHeader);
mParams.putAll(params);
buildMultipartEntity();
@Override
public Map<String, String> getHeaders() throws AuthFailureError
Map<String, String> headers = super.getHeaders();
if (headers == null
|| headers.equals(Collections.emptyMap()))
headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
return headers;
private void buildMultipartEntity()
int count = 0;
for (String key : mFiles.keySet())
File file = mFiles.get(key);
String fileName = file.getName();
mBuilder.addBinaryBody(key, file, ContentType.create("image/jpeg"), fileName);
try
for (String key : mParams.keySet())
mBuilder.addTextBody(key, mParams.get(key));
catch (Exception e)
VolleyLog.e("Exception");
mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mBuilder.setLaxMode().setBoundary("xx").setCharset(Charset.forName("UTF-8"));
@Override
public String getBodyContentType()
return mBuilder.build().getContentType().getValue();
@Override
public byte[] getBody() throws AuthFailureError
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try
HttpEntity httpEntity= mBuilder.build(); /// application crash our here
httpEntity.writeTo(bos);
catch (IOException e)
VolleyLog.e("IOException writing to ByteArrayOutputStream bos, building the multipart request.");
return bos.toByteArray();
@Override
protected void deliverResponse(T response)
listener.onResponse(response);
我正在使用implementation files('libs/httpclient-osgi-4.3.jar')
和截击implementation 'com.android.volley:volley:1.1.0'
【问题讨论】:
【参考方案1】:试试这个。 Proguard 应该忽略外部库,因为外部库已经被压缩。
有时,再次重新压缩外部库时,proguard 可能会导致错误
-keep class org.apache.** *;
在上面添加到下面
-dontwarn org.apache.http.**
-keep class org.apache.** *; // add it here
参考:How to make Proguard ignore external libraries?
【讨论】:
【参考方案2】:首先你将 httpclient-osgi-4.3.jar 从here更新为最新的
然后修改progurd规则以保持类如下
-keep class org.apache.** *;
【讨论】:
以上是关于启用 proguard 后 java.lang.NoSuchMethodError Org/apache/http/util/ByteArrayBuffer的主要内容,如果未能解决你的问题,请参考以下文章
启用 proguard 后无法访问 kotlin 类中使用的伴随对象
在 gradle 中启用 Proguard 后 FCM 不起作用
启用proguard后Realm中的ClassNotFoundException
启用 proguard 后 java.lang.NoSuchMethodError Org/apache/http/util/ByteArrayBuffer