Android 开源框架 ( 三 ) 基于OkHttp进一步封装的OkHttpUtils介绍
OkHttpUtils是 廖子尧 是基于OkHttp封装的框架库。里面也封装了很多其他实用的一些组件,这里只介绍下网络相关的使用。
里面的上传下载功能使用队列的概念做了进一步封装,但是因为我使用的是旧库,对于android6.0运行时权限判断和android7.0私有文件权限设置没有处理。
同上一篇随笔一样分析:Android 开源框架 ( 二 ) 基于OkHttp进一步封装的okhttp-utils介绍 介绍下基本使用,加深自己对OkHttp的理解。
一.引入到自己项目后,先来对比下同上一篇介绍的okhttp-utils类库目录对比下:
注意:途中下面红框标注部分的module:okhttputils-lib是本文介绍的OkHttpUtils类库,上面的module:okhttputils是Android 开源框架 ( 二 ) 基于OkHttp进一步封装的okhttp-utils介绍介绍的框架类库。
两个封装框架都有一个 OkHttpUtils 入口类。
二. OkHttpUtils基本使用
1.//get 请求数据
OkHttpUtils.get(Urls.URL_METHOD)// .tag(this)// .headers("header1", "headerValue1")// .params("param1", "paramValue1")// .execute(new MethodCallBack<>(this, RequestInfo.class));
2.//post 请求数据
OkHttpUtils.post(Urls.URL_METHOD)// .tag(this)// .headers("header1", "headerValue1")// .params("param1", "paramValue1")// .execute(new MethodCallBack<>(this, RequestInfo.class));
3.//缓存请求
OkHttpUtils.get(Urls.URL_CACHE)// .tag(this)// .cacheMode(CacheMode.DEFAULT)// .cacheKey("cache_default")// .cacheTime(5000)//对于默认的缓存模式,该时间无效,依靠的是服务端对304缓存的控制 .headers("header1", "headerValue1")// .params("param1", "paramValue1")// .execute(new CacheCallBack(this));
public enum CacheMode { /** 按照HTTP协议的默认缓存规则,例如有304响应头时缓存 */ DEFAULT, /** 不使用缓存 */ NO_CACHE, /** 请求网络失败后,读取缓存 */ REQUEST_FAILED_READ_CACHE, /** 如果缓存不存在才请求网络,否则使用缓存 */ IF_NONE_CACHE_REQUEST, /** 先使用缓存,不管是否存在,仍然请求网络 */ FIRST_CACHE_THEN_REQUEST, }
4.//批量上传文件
4.1 方法一:
OkHttpUtils.post(Urls.URL_FORM_UPLOAD)// .tag(this)// .headers("header1", "headerValue1")// .headers("header2", "headerValue2")// .params("param1", "paramValue1")// .params("param2", "paramValue2")// // .params("file1",new File("文件路径")) //这种方式为一个key,对应一个文件 // .params("file2",new File("文件路径")) // .params("file3",new File("文件路径")) .addFileParams("file", files) // 这种方式为同一个key,上传多个文件 .execute(new ProgressUpCallBack<>(this, RequestInfo.class));
4.2 方式二:
for (int i = 0; i < images.size(); i++) { //注册监听 MyUploadListener listener = new MyUploadListener(); listener.setUserTag(gridView.getChildAt(i)); //批量加入上传队列 UploadManager.getInstance(getContext()).addTask(Urls.URL_FORM_UPLOAD, new File(images.get(i).path), "imageFile", listener); }
/** 一旦该方法执行,意味着开始下载了 */ @Override protected UploadInfo doInBackground(Void... params) { if (isCancelled()) return mUploadInfo; L.e("doInBackground:" + mUploadInfo.getResourcePath()); mUploadInfo.setNetworkSpeed(0); mUploadInfo.setState(UploadManager.UPLOADING); postMessage(null, null, null); //构建请求体,默认使用post请求上传 Response response; try { //本质还是调用OkHttpUtils的post方法上传 PostRequest postRequest = OkHttpUtils.post(mUploadInfo.getUrl()); File resource = new File(mUploadInfo.getResourcePath()); if (TextUtils.isEmpty(mUploadInfo.getFileName())) { mUploadInfo.setFileName(resource.getName()); } postRequest.params(mUploadInfo.getKey(), resource, mUploadInfo.getFileName()); //接口对接,数据回调 postRequest.setCallback(new MergeListener()); response = postRequest.execute(); } catch (IOException e) { e.printStackTrace(); mUploadInfo.setNetworkSpeed(0); mUploadInfo.setState(UploadManager.ERROR); postMessage(null, "网络异常", e); return mUploadInfo; } if (response.isSuccessful()) { //解析过程中抛出异常,一般为 json 格式错误,或者数据解析异常 try { T t = (T) mUploadInfo.getListener().parseNetworkResponse(response); mUploadInfo.setNetworkSpeed(0); mUploadInfo.setState(UploadManager.FINISH); //上传成功 postMessage(t, null, null); return mUploadInfo; } catch (Exception e) { e.printStackTrace(); mUploadInfo.setNetworkSpeed(0); mUploadInfo.setState(UploadManager.ERROR); postMessage(null, "解析数据对象出错", e); return mUploadInfo; } } else { mUploadInfo.setNetworkSpeed(0); mUploadInfo.setState(UploadManager.ERROR); postMessage(null, "数据返回失败", null); return mUploadInfo; } }
5.//批量下载文件
5.1 方式一:
OkHttpUtils.get(Urls.URL_DOWNLOAD)// .tag(this)// .headers("header1", "headerValue1")// .params("param1", "paramValue1")// .execute(new DownloadFileCallBack(Environment.getExternalStorageDirectory() + "/temp", "OkHttpUtils.apk"));
5.2 方式二(DownloadManager):
if (downloadManager.getTaskByUrl(apk.getUrl()) != null) { Toast.makeText(getContext(), "任务已经在下载列表中", Toast.LENGTH_SHORT).show(); } else { downloadManager.addTask(apk.getUrl(), null); AppCacheUtils.getInstance(getContext()).put(apk.getUrl(), apk); download.setText("已在队列"); download.setEnabled(false); }
/** 一旦该方法执行,意味着开始下载了 */ @Override protected DownloadInfo doInBackground(Void... params) { if (isCancelled()) return mDownloadInfo; L.e("doInBackground:" + mDownloadInfo.getFileName()); mPreviousTime = System.currentTimeMillis(); mDownloadInfo.setNetworkSpeed(0); mDownloadInfo.setState(DownloadManager.DOWNLOADING); postMessage(null, null); //构建下载文件路径,如果有设置,就用设置的,否者就自己创建 String url = mDownloadInfo.getUrl(); String fileName = mDownloadInfo.getFileName(); if (TextUtils.isEmpty(fileName)) { fileName = getUrlFileName(url); mDownloadInfo.setFileName(fileName); } if (TextUtils.isEmpty(mDownloadInfo.getTargetPath())) { File file = new File(mDownloadInfo.getTargetFolder(), fileName); mDownloadInfo.setTargetPath(file.getAbsolutePath()); } //检查手机上文件的有效性 File file = new File(mDownloadInfo.getTargetPath()); long startPos; if (file.length() != mDownloadInfo.getDownloadLength()) { mDownloadInfo.setNetworkSpeed(0); mDownloadInfo.setState(DownloadManager.ERROR); postMessage("断点文件异常,需要删除后重新下载", null); return mDownloadInfo; } else { //断点下载的情况 startPos = mDownloadInfo.getDownloadLength(); } //再次检查文件有效性,文件大小大于总文件大小 if (startPos > mDownloadInfo.getTotalLength()) { mDownloadInfo.setNetworkSpeed(0); mDownloadInfo.setState(DownloadManager.ERROR); postMessage("断点文件异常,需要删除后重新下载", null); return mDownloadInfo; } if (startPos == mDownloadInfo.getTotalLength() && startPos > 0) { mDownloadInfo.setProgress(1.0f); mDownloadInfo.setNetworkSpeed(0); mDownloadInfo.setState(DownloadManager.FINISH); postMessage(null, null); return mDownloadInfo; } //设置断点写文件 ProgressRandomAccessFile randomAccessFile; try { randomAccessFile = new ProgressRandomAccessFile(file, "rw", startPos); } catch (FileNotFoundException e) { e.printStackTrace(); mDownloadInfo.setNetworkSpeed(0); mDownloadInfo.setState(DownloadManager.ERROR); postMessage("没有找到已存在的断点文件", e); return mDownloadInfo; } L.e("startPos:" + startPos + " path:" + mDownloadInfo.getTargetPath()); //构建请求体,默认使用get请求下载,设置断点头 Response response; try { response = OkHttpUtils.get(url).headers("RANGE", "bytes=" + startPos + "-").execute(); } catch (IOException e) { e.printStackTrace(); mDownloadInfo.setNetworkSpeed(0); mDownloadInfo.setState(DownloadManager.ERROR); postMessage("网络异常", e); return mDownloadInfo; } //获取流对象,准备进行读写文件 long totalLength = response.body().contentLength(); if (mDownloadInfo.getTotalLength() == 0) { mDownloadInfo.setTotalLength(totalLength); } InputStream is = response.body().byteStream(); //读写文件流 try { download(is, randomAccessFile); } catch (IOException e) { e.printStackTrace(); mDownloadInfo.setNetworkSpeed(0); mDownloadInfo.setState(DownloadManager.ERROR); postMessage("文件读写异常", e); return mDownloadInfo; } //循环结束走到这里,a.下载完成 b.暂停 c.判断是否下载出错 if (isCancelled()) { L.e("state: 暂停" + mDownloadInfo.getState()); mDownloadInfo.setNetworkSpeed(0); if (isPause) mDownloadInfo.setState(DownloadManager.PAUSE); //暂停 else mDownloadInfo.setState(DownloadManager.NONE); //停止 postMessage(null, null); } else if (file.length() == mDownloadInfo.getTotalLength() && mDownloadInfo.getState() == DownloadManager.DOWNLOADING) { mDownloadInfo.setNetworkSpeed(0); mDownloadInfo.setState(DownloadManager.FINISH); //下载完成 postMessage(null, null); } else if (file.length() != mDownloadInfo.getDownloadLength()) { mDownloadInfo.setNetworkSpeed(0); mDownloadInfo.setState(DownloadManager.ERROR); //由于不明原因,文件保存有误 postMessage("未知原因", null); } return mDownloadInfo; }