Android Retrofit 2文件上传不起作用 [英] Android Retrofit 2 file upload is not working

查看:180
本文介绍了Android Retrofit 2文件上传不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想开发一个可以将任何类型的文件上传到服务器的应用程序.我得到了源代码.但这仅适用于图像.并且只能上传2 MB以下的图像文件.我想上传所有类型的文件.请帮我.我的代码如下所示.

I want to develop an app which is upload any type of file to sever. I got source code. But it is working only for images. And only upload below 2 MB size of image files. I want to upload all type of files. Please help me. My codes are shown below.

MainActivity.java

MainActivity.java

public class MainActivity extends AppCompatActivity {
Service service;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button btn = (Button) findViewById(R.id.btn_upload);

    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();

    // Change base URL to your upload server URL.
    service = new Retrofit.Builder().baseUrl("http://192.168.1.4/work/filesharing/").client(client).build().create(Service.class);

    if (btn != null) {
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                String filePath1 = "/storage/emulated/0/gt.png";

                File file = new File(filePath1);

                RequestBody reqFile = RequestBody.create(MediaType.parse("*/*"), file);
                MultipartBody.Part body = MultipartBody.Part.createFormData("uploaded_file", file.getName(), reqFile);
                RequestBody name = RequestBody.create(MediaType.parse("text/plain"), "upload_test");



                retrofit2.Call<okhttp3.ResponseBody> req = service.postImage(body, name);
                req.enqueue(new Callback<ResponseBody>() {
                    @Override
                    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { }

                    @Override
                    public void onFailure(Call<ResponseBody> call, Throwable t) {
                        t.printStackTrace();

                        Log.d("failure", "message = " + t.getMessage());
                        Log.d("failure", "cause = " + t.getCause());
                    }
                });

            }
        });
    }
}

}

上传2MB以上的zip文件时将显示错误.

Error will showing when upload the zip file above 2MB.

11-14 17:09:14.369 13895-13960/app3.acs.com.file_upload2 D/OpenGLRenderer: Enabling debug mode 0
11-14 17:09:16.068 13895-13993/app3.acs.com.file_upload2 D/OkHttp: --> POST http://192.168.1.4/work/filesharing/6.php HTTP/1.1
11-14 17:09:16.068 13895-13993/app3.acs.com.file_upload2 D/OkHttp: Content-Type: multipart/form-data; boundary=b2c1d03e-f7a5-4e3f-89e1-d1c20358f7dc
11-14 17:09:16.070 13895-13993/app3.acs.com.file_upload2 D/OkHttp: Content-Length: 20862337
11-14 17:09:16.934 13895-13919/app3.acs.com.file_upload2 W/art: Suspending all threads took: 30.363ms
11-14 17:09:16.935 13895-13993/app3.acs.com.file_upload2 I/art: Alloc partial concurrent mark sweep GC freed 20318(40MB) AllocSpace objects, 0(0B) LOS objects, 35% free, 28MB/44MB, paused 644us total 49.776ms
11-14 17:09:18.272 13895-13993/app3.acs.com.file_upload2 I/art: Alloc sticky concurrent mark sweep GC freed 8(256B) AllocSpace objects, 0(0B) LOS objects, 10% free, 68MB/76MB, paused 1.012ms total 6.892ms
11-14 17:09:18.293 13895-13993/app3.acs.com.file_upload2 I/art: Alloc partial concurrent mark sweep GC freed 6(192B) AllocSpace objects, 0(0B) LOS objects, 18% free, 68MB/84MB, paused 1.310ms total 18.796ms
11-14 17:09:18.330 13895-13993/app3.acs.com.file_upload2 I/art: Alloc concurrent mark sweep GC freed 6(12KB) AllocSpace objects, 0(0B) LOS objects, 18% free, 68MB/84MB, paused 627us total 34.490ms
11-14 17:09:18.332 13895-13993/app3.acs.com.file_upload2 I/art: Forcing collection of SoftReferences for 36MB allocation
11-14 17:09:18.371 13895-13993/app3.acs.com.file_upload2 I/art: Alloc concurrent mark sweep GC freed 11(344B) AllocSpace objects, 0(0B) LOS objects, 18% free, 68MB/84MB, paused 569us total 38.975ms
11-14 17:09:18.373 13895-13993/app3.acs.com.file_upload2 E/art: Throwing OutOfMemoryError "Failed to allocate a 38772598 byte allocation with 16777120 free bytes and 27MB until OOM"
11-14 17:09:18.381 13895-13993/app3.acs.com.file_upload2 E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
                                                                       Process: app3.acs.com.file_upload2, PID: 13895
                                                                       java.lang.OutOfMemoryError: Failed to allocate a 38772598 byte allocation with 16777120 free bytes and 27MB until OOM
                                                                           at java.lang.String.<init>(String.java:332)
                                                                           at java.lang.String.<init>(String.java:371)
                                                                           at okio.Buffer.readString(Buffer.java:579)
                                                                           at okio.Buffer.readString(Buffer.java:562)
                                                                           at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:195)
                                                                           at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:187)
                                                                           at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
                                                                           at okhttp3.RealCall.access$100(RealCall.java:30)
                                                                           at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
                                                                           at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
                                                                           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:818)
11-14 17:09:20.069 13895-13993/app3.acs.com.file_upload2 I/Process: Sending signal. PID: 13895 SIG: 9

推荐答案

我在上传大型图片或视频时遇到了同样的问题.主要问题是您在HttpLoggingInterceptor中使用主体级别,而记录器正在logcat中打印文件,从而触发java.lang.OutOfMemoryError异常.

I had the same problem uploading large images or videos. The main problem is you're using body level in HttpLoggingInterceptor, and logger is printing your file in logcat triggering a java.lang.OutOfMemoryError exception.

如果您不想禁用主体级别的登录,则可以添加此代码,以避免登录生成大文件内容.我创建了自己的HttpLoggingInterceptor并添加了if条件,以在content-length> 10Ks的情况下跳过主体登录.

If you don't want to disable the body level loggin you can add this code to avoid loggin to print big large files content. I created my own HttpLoggingInterceptor and add an if condition to skip body loggin in case of content-length > 10Ks.

HttpLoggingInterceptor是最终类,因此您不能覆盖它.您可以复制HttpLoggingInterceptor文件并替换此原始代码:

HttpLoggingInterceptor is a final class, so you can't override it. You can make a copy of HttpLoggingInterceptor file and replace this original code:

if (!logBody || !hasRequestBody) {
            logger.log("--> END " + request.method());
        } else if (bodyEncoded(request.headers())) {
            logger.log("--> END " + request.method() + " (encoded body omitted)");
        } else {
            Buffer buffer = new Buffer();
            requestBody.writeTo(buffer);
            //[...]

使用以下代码:

if (!logBody || !hasRequestBody) {
            logger.log("--> END " + request.method());
        } else if (bodyEncoded(request.headers())) {
            logger.log("--> END " + request.method() + " (encoded body omitted)");
        } else if (requestBody.contentLength()>1024 * 10) { //>10Kb
            logger.log("--> END " + request.method() + " (contentLength > 10Kb --> omitted)");
        } else {
            Buffer buffer = new Buffer();
            requestBody.writeTo(buffer);
            //[...]

我希望这可以帮助任何人.对不起,我的英语;).

I hope this can help anyone. And sorry for my English ;).

这篇关于Android Retrofit 2文件上传不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆