android开发之OkHttp上传byte数组

最近准备对老项目改造安卓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 <T> 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();
            }
        }

    };
}

经过测试可用,记录一下;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章