【问题标题】:Android Multipart Form File upload in Marshmallow在 Marshmallow 中上传 Android 多部分表单文件
【发布时间】:2016-10-18 08:52:07
【问题描述】:

我正在尝试使用多部分表单将文件上传到服务器。 自 API 23 起,Android 已弃用 Apache HTTP 库。

我改用 OkHttp 来上传文件,如下所示:

        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart(name, fileName, requestBodyPart)
                .build();

        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();

requestBodyPart 是:

        requestBodyPart = new RequestBody() {
            @Override
            public MediaType contentType() {
                return MediaType.parse(contentType);
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                try {
                    if (sink.writeAll(Okio.source(inputStream)) == 0) {
                        throw new IOException("Empty File!");
                    }
                } finally {
                    MiscUtils.closeCloseable(inputStream);
                }
            }
        };

但是,在文件上传方面,OkHttp 似乎不是那么好。很多超时,似乎正在创建几个抽象层(源和接收器),并且在文件数据仍在通过套接字写入时触发此 AsyncTimeout。

对于使用 API 23 及更高版本的 Android 进行多部分文件上传,是否有任何建议。我知道我可以包含 HTTP 遗留库,但由于它已被删除,我不想这样做。或者有什么办法可以提高 OkHttp 的性能?

【问题讨论】:

    标签: android file-upload okhttp okhttp3


    【解决方案1】:

    这应该可以工作

    String name = ...
    File file = ...
    MediaType mediaType = MediaType.parse(...)
    OkHttpClient httpClient = ...
    Request request = new Request.Builder()
            .url(url)
            .post(new MultipartBuilder().type(MultipartBuilder.FORM)
                                        .addFormDataPart(name,
                                                         file.getName(),
                                                         RequestBody.create(mediaType, file))
                                        .build())
            .build();
    try {
        Response response = httpClient.newCall(request).execute();
    } catch (IOException e) {
        // handle error
    }
    

    【讨论】:

    • 感谢您的回复。是的,我正在使用它。问题在于,对于稍大的文件或在写入文件时发生超时的慢速网络,它的性能不佳。
    • 在任何数据写入套接字之前不应发生超时。您可以使用OkHttpClient httpClient = new OkHttpClient(); httpClient.setConnectTimeout(30, TimeUnit.SECONDS); httpClient.setReadTimeout(30, TimeUnit.SECONDS); 配置超时
    • 我现在实际上已经设置为超过 3 分钟。发生的情况是一个大文件的最后一个字节仍然没有传输到 AsyncTimeout 启动的套接字(我猜是因为底层套接字正在缓冲一些数据)。 AsyncTimeout 在套接字上不起作用,而是在具有 sleep() 的应用程序上工作,并且它在响应从服务器返回之前触发,即使它自己的套接字还没有超时。
    猜你喜欢
    • 2018-10-15
    • 2020-05-27
    • 2016-04-08
    • 2012-04-10
    • 2017-01-10
    • 1970-01-01
    • 2021-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多