请查看我用于将视频上传到服务器的以下代码。但是,对于足够大的视频,我会遇到 OutOfMemory 异常。
InputStream stream = getContentResolver().openInputStream(videoUri);
byte[] byteArray = IOUtils.toByteArray(stream);
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", "fname",
RequestBody.create(MediaType.parse("video/mp4"), byteArray))
.build();
Request request = new Request.Builder()
.url(uploadURL)
.post(requestBody)
.build();
OkHttpClient client = new OkHttpClient.Builder().build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
有人能为我指出正确的方向,帮助我避免 OutOfMemory 异常吗?有什么方法可以从 InputStream 转到 requestBody?
最佳答案
您可以创建一个自定义的 RequestBody
来传输数据。您必须小心:它可能会被多次重用,因为 OkHttp 可能会决定重试请求。确保每次都能从头开始重新打开 InputStream
。
ContentResolver contentResolver = context.getContentResolver();
final String contentType = contentResolver.getType(videoUri);
final AssetFileDescriptor fd = contentResolver.openAssetFileDescriptor(videoUri, "r");
if (fd == null) {
throw new FileNotFoundException("could not open file descriptor");
}
RequestBody videoFile = new RequestBody() {
@Override public long contentLength() { return fd.getDeclaredLength(); }
@Override public MediaType contentType() { return MediaType.parse(contentType); }
@Override public void writeTo(BufferedSink sink) throws IOException {
try (InputStream is = fd.createInputStream()) {
sink.writeAll(Okio.buffer(Okio.source(is)));
}
}
};
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", "fname", videoFile)
.build();
Request request = new Request.Builder()
.url(uploadURL)
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(Call call, IOException e) {
try {
fd.close();
} catch (IOException ex) {
e.addSuppressed(ex);
}
Log.e(TAG, "failed", e);
}
@Override public void onResponse(Call call, Response response) throws IOException {
fd.close();
}
});
关于Android - 如何使用 OkHTTP 分块上传视频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45123696/