【问题标题】:java.lang.NoSuchMethodError Lorg/apache/http/util/ByteArrayBuffer after enabling progurd启用 proguard 后 java.lang.NoSuchMethodError Org/apache/http/util/ByteArrayBuffer
【发布时间】: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'

【问题讨论】:

    标签: android apache-httpclient-4.x android-proguard


    【解决方案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.** { *; }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-16
        • 1970-01-01
        • 2015-03-14
        相关资源
        最近更新 更多