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;
    }    

 

posted @ 2018-07-29 22:51  FreeFunCode  阅读(1120)  评论(0编辑  收藏  举报