最近准备对老项目改造安卓9.0兼容,之前app请求是封装的org.apache.http.legacy.jar这个包,而这个包再9.0的模拟器上会无法访问,因此需要进行改造,而我的方案是直接改封装底层为okhttp,简单快捷;
okhttp的 get post postfile网上都有,我就不赘述了;这里讲一下网上找不到的,okhttp上传byte[];
okhttp将文件上传封装了,只需要传入filepath即可上传,而这个与大家通常的需求不相符合:
通常大家最常见的上传都是针对图片上传,经常会采用图像压缩降低上传文件大小,而我们已经压缩好了希望直接上传即可,而不是保存到本地然后再上传;
这个东西我百度了一下,发现有人也在问,但是没人给出方案,我之前也没有用过okhttp,所以我先看别人上传文件怎么写的,于是我看到了这篇文章:http://www.cnblogs.com/whoislcj/p/5529827.html
经过观察我发现了这个:
看到这个大家就明白了,okhttp的文件上传操作就受到这里控制的,writeTo这个方法就是向服务端写入byte数据用的,看文章里面的代码可用看出来,这里的操作就是读取本地文件,写入buffer,最后write;
大家看出来了,其实okhttp封装的上传其实也是直接传byte[],只是它封装了一层,只让我们传文件名,后面的操作不可见了而已,我们要传现成的byte[],只需要重写这个方法,直接写入byte[]就可以了
于是我就写了这个方法:
private String okhttpPostFile_forBytes()
{
try {
//补全请求地址
MultipartBody.Builder builder = new MultipartBody.Builder();
//设置类型
builder.setType(MultipartBody.FORM);
//追加参数
for (NameValuePair item : params) {
builder.addFormDataPart(item.key, item.value);
}
File file=null;
builder.addFormDataPart("file", "imgs.jpg", createProgressRequestBody( MediaType.parse("application/octet-stream"), file));
//创建RequestBody
RequestBody body = builder.build();
//创建Request
final Request request = new Request.Builder().url(mUrl).post(body).build();
OkHttpClient mOkHttpClient = new OkHttpClient();
final Call call = mOkHttpClient.newBuilder().writeTimeout(50, TimeUnit.SECONDS).build().newCall(request);
try
{
Response response = call.execute();
if (response.isSuccessful()) {
return response.body().string();
}
else
{
Logger.e("rest", "okhttp-post-err:" + response.code());
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
还有下面这个方法:
public RequestBody createProgressRequestBody(final MediaType contentType, final File file) {
return new RequestBody() {
@Override
public MediaType contentType() {
return contentType;
}
@Override
public long contentLength() {
if (mfileData!=null)
return mfileData.length;
return file.length();
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
Source source;
try {
if (mfileData!=null)
{
source =Okio.source(new ByteArrayInputStream(mfileData));
Buffer buf = new Buffer();
long remaining = contentLength();
long current = 0;
for (long readCount; (readCount = source.read(buf, 2048)) != -1; ) {
sink.write(buf, readCount);
current += readCount;
//callback 进度通知
}
}
else
{
source = Okio.source(file);
Buffer buf = new Buffer();
long remaining = contentLength();
long current = 0;
for (long readCount; (readCount = source.read(buf, 2048)) != -1; ) {
sink.write(buf, readCount);
current += readCount;
//callback 进度通知
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
}
经过测试可用,记录一下;