我需要使用okhttp将apk中捆绑的二进制文件上传到服务器.使用urlconnection,您只需获取资产的输入流,然后将其放入您的请求中.但是,okhttp只提供上传字节数组,字符串或文件的选项.由于您无法获取apk中捆绑的资产的文件路径,因此将文件复制到本地文件目录的唯一选项(我宁愿不这样做)然后将文件提供给okhttp?有没有办法简单地使用assetinputstream直接向Web服务器发出请求?
编辑:我使用了接受的答案,但我没有创建一个静态实用程序类,而只是将子类化为RequestBody
public class InputStreamRequestBody extends RequestBody { private InputStream inputStream; private MediaType mediaType; public static RequestBody create(final MediaType mediaType, final InputStream inputStream) { return new InputStreamRequestBody(inputStream, mediaType); } private InputStreamRequestBody(InputStream inputStream, MediaType mediaType) { this.inputStream = inputStream; this.mediaType = mediaType; } @Override public MediaType contentType() { return mediaType; } @Override public long contentLength() { try { return inputStream.available(); } catch (IOException e) { return 0; } } @Override public void writeTo(BufferedSink sink) throws IOException { Source source = null; try { source = Okio.source(inputStream); sink.writeAll(source); } finally { Util.closeQuietly(source); } } }
我对这种方法唯一关心的是inputstream.available()对于内容长度的不可靠性.静态构造函数是为了匹配okhttp的内部实现
您可能无法使用库直接执行此操作,但您可以创建一个小实用程序类来为您执行此操作.然后,您可以在任何需要的地方重复使用它.
public class RequestBodyUtil { public static RequestBody create(final MediaType mediaType, final InputStream inputStream) { return new RequestBody() { @Override public MediaType contentType() { return mediaType; } @Override public long contentLength() { try { return inputStream.available(); } catch (IOException e) { return 0; } } @Override public void writeTo(BufferedSink sink) throws IOException { Source source = null; try { source = Okio.source(inputStream); sink.writeAll(source); } finally { Util.closeQuietly(source); } } }; } }
然后就这样简单地使用它
OkHttpClient client = new OkHttpClient(); MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8"); InputStream inputStream = getAssets().open("README.md"); RequestBody requestBody = RequestBodyUtil.create(MEDIA_TYPE_MARKDOWN, inputStream); Request request = new Request.Builder() .url("https://api.github.com/markdown/raw") .post(requestBody) .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); Log.d("POST", response.body().string());
此示例代码基于此代码.替换Assets
文件名和MediaType
您自己的名称.