OkGo的详解_okr什么意思简单来说[通俗易懂]

OkGo的详解_okr什么意思简单来说[通俗易懂]一okgo的简介该库是封装了okhttp的标准RESTful风格的网络框架,可以与RxJava完美结合,比Retrofit更简单易用

OkGo的详解_okr什么意思简单来说[通俗易懂]"

一 okgo的简介

该库是封装了okhttp的标准RESTful风格的网络框架,可以与RxJava完美结合,比Retrofit更简单易用。支持大文件上传下载,上传进度回调,下载进度回调,表单上传(多文件和多参数一起上传),链式调用,可以自定义返回对象,支持Https和自签名证书,支持超时自动重连,支持cookie与session的自动管理,支持四种缓存模式缓存网络数据,支持301、302重定向,扩展了统一的上传管理和下载管理功能。


二 okgo的使用介绍

2.1 build.gradle添加依赖

compile 'com.lzy.net:okgo:3.0.4'

2.2 权限设置

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

2.3 Application中全局配置

一般在Aplication,或者基类中配置,只需要调用一次即可

  • 可以配置log开关
  • 全局的超时时间
  • 全局cookie管理策略
  • Https配置
  • 超时重连次数
  • 公共的请求头和请求参数等信息

注意:不要忘记了在清单文件中注册 Application

  private void initOkGo() {
        //---------这里给出的是示例代码,告诉你可以这么传,实际使用的时候,根据需要传,不需要就不传-------------//
        HttpHeaders headers = new HttpHeaders();
        headers.put("commonHeaderKey1", "commonHeaderValue1");    //header不支持中文,不允许有特殊字符
        headers.put("commonHeaderKey2", "commonHeaderValue2");
        HttpParams params = new HttpParams();
        params.put("commonParamsKey1", "commonParamsValue1");     //param支持中文,直接传,不要自己编码
        params.put("commonParamsKey2", "这里支持中文参数");
        //----------------------------------------------------------------------------------------//

        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        //log相关
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("OkGo");
        loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);        //log打印级别,决定了log显示的详细程度
        loggingInterceptor.setColorLevel(Level.INFO);                               //log颜色级别,决定了log在控制台显示的颜色
        builder.addInterceptor(loggingInterceptor);                                 //添加OkGo默认debug日志
        //第三方的开源库,使用通知显示当前请求的log,不过在做文件下载的时候,这个库好像有问题,对文件判断不准确
        //builder.addInterceptor(new ChuckInterceptor(this));

        //超时时间设置,默认60秒
        builder.readTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);      //全局的读取超时时间
        builder.writeTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);     //全局的写入超时时间
        builder.connectTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);   //全局的连接超时时间

        //自动管理cookie(或者叫session的保持),以下几种任选其一就行
        //builder.cookieJar(new CookieJarImpl(new SPCookieStore(this)));            //使用sp保持cookie,如果cookie不过期,则一直有效
        builder.cookieJar(new CookieJarImpl(new DBCookieStore(this)));              //使用数据库保持cookie,如果cookie不过期,则一直有效
        //builder.cookieJar(new CookieJarImpl(new MemoryCookieStore()));            //使用内存保持cookie,app退出后,cookie消失

        //https相关设置,以下几种方案根据需要自己设置
        //方法一:信任所有证书,不安全有风险
        HttpsUtils.SSLParams sslParams1 = HttpsUtils.getSslSocketFactory();
        //方法二:自定义信任规则,校验服务端证书
        HttpsUtils.SSLParams sslParams2 = HttpsUtils.getSslSocketFactory(new SafeTrustManager());
        //方法三:使用预埋证书,校验服务端证书(自签名证书)
        //HttpsUtils.SSLParams sslParams3 = HttpsUtils.getSslSocketFactory(getAssets().open("srca.cer"));
        //方法四:使用bks证书和密码管理客户端证书(双向认证),使用预埋证书,校验服务端证书(自签名证书)
        //HttpsUtils.SSLParams sslParams4 = HttpsUtils.getSslSocketFactory(getAssets().open("xxx.bks"), "123456", getAssets().open("yyy.cer"));
        builder.sslSocketFactory(sslParams1.sSLSocketFactory, sslParams1.trustManager);
        //配置https的域名匹配规则,详细看demo的初始化介绍,不需要就不要加入,使用不当会导致https握手失败
        builder.hostnameVerifier(new SafeHostnameVerifier());

        // 其他统一的配置
        // 详细说明看GitHub文档:https://github.com/jeasonlzy/
        OkGo.getInstance().init(this)                           //必须调用初始化
                .setOkHttpClient(builder.build())               //建议设置OkHttpClient,不设置会使用默认的
                .setCacheMode(CacheMode.NO_CACHE)               //全局统一缓存模式,默认不使用缓存,可以不传
                .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)   //全局统一缓存时间,默认永不过期,可以不传
                .setRetryCount(3)                               //全局统一超时重连次数,默认为三次,那么最差的情况会请求4次(一次原始请求,三次重连请求),不需要可以设置为0
                .addCommonHeaders(headers)                      //全局公共头
                .addCommonParams(params);                       //全局公共参数
    }

    /**
     * 这里只是我谁便写的认证规则,具体每个业务是否需要验证,以及验证规则是什么,请与服务端或者leader确定
     * 这里只是我谁便写的认证规则,具体每个业务是否需要验证,以及验证规则是什么,请与服务端或者leader确定
     * 这里只是我谁便写的认证规则,具体每个业务是否需要验证,以及验证规则是什么,请与服务端或者leader确定
     * 重要的事情说三遍,以下代码不要直接使用
     */
    private class SafeTrustManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            try {
                for (X509Certificate certificate : chain) {
                    certificate.checkValidity(); //检查证书是否过期,签名是否通过等
                }
            } catch (Exception e) {
                throw new CertificateException(e);
            }
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }

    /**
     * 这里只是我谁便写的认证规则,具体每个业务是否需要验证,以及验证规则是什么,请与服务端或者leader确定
     * 这里只是我谁便写的认证规则,具体每个业务是否需要验证,以及验证规则是什么,请与服务端或者leader确定
     * 这里只是我谁便写的认证规则,具体每个业务是否需要验证,以及验证规则是什么,请与服务端或者leader确定
     * 重要的事情说三遍,以下代码不要直接使用
     */
    private class SafeHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            //验证主机名是否匹配
            //return hostname.equals("server.jeasonlzy.com");
            return true;
        }
    }

最简单的如果上面的配置OkHttpClient不想写,就用okgo中默认的,一行代码就可以完成。

OkGo.getInstance().init(this);

2.4 get请求

/**
   * get请求获取数据
   * @param url
   */
  private void getByOkGo(String url){
      OkGo.get(url)                            // 请求方式和请求url
              .tag(this)                       // 请求的 tag, 主要用于取消对应的请求
              .cacheKey("cacheKey")            // 设置当前请求的缓存key,建议每个不同功能的请求设置一个,如果不指定cacheKey,默认是用url带参数的全路径名为cacheKey。
              .cacheMode(CacheMode.DEFAULT)    // 缓存模式
              .execute(new StringCallback() {
                  @Override
                  public void onSuccess(String s, Call call, Response response) {
                      mTextView2.setText(s);
                  }
              });
  }

这里简单说一下缓存模式cacheMode
一共有五种CacheMode缓存模式

  • NO_CACHE:不使用缓存,该模式下cacheKey、cacheTime 参数均无效
  • DEFAULT:按照HTTP协议的默认缓存规则,例如有304响应头时缓存。
  • REQUEST_FAILED_READ_CACHE:先请求网络,如果请求网络失败,则读取缓存,如果读取缓存失败,本次请求失败。
  • IF_NONE_CACHE_REQUEST:如果缓存不存在才请求网络,否则使用缓存。
  • FIRST_CACHE_THEN_REQUEST:先使用缓存,不管是否存在,仍然请求网络。

使用缓存的场景比如:下拉刷新(上拉刷新不需要)CacheMode设置为 IF_NONE_CACHE_REQUEST,效果就是当用户网络没有的时候不至于出现白板的现象。

注意点:
缓存的对象bean必须实现Serializable接口,否者会报NotSerializableException。因为缓存的原理是将对象序列化后直接写入数据库中,如果不实现Serializable接口,会导致对象无法序列化,进而无法写入到数据库中,也就达不到缓存的效果。

 //下拉刷新
  @Override
    public void onRefresh() {
        OkGo.<GankResponse<List<GankModel>>>get(url + "1")//
                .cacheKey("TabFragment_" + fragmentTitle)       //由于该fragment会被复用,必须保证key唯一,否则数据会发生覆盖
                .cacheMode(CacheMode.FIRST_CACHE_THEN_REQUEST)  //缓存模式先使用缓存,然后使用网络数据
                .execute(new NewsCallback<GankResponse<List<GankModel>>>() {
                    @Override
                    public void onSuccess(Response<GankResponse<List<GankModel>>> response) {
                        List<GankModel> results = response.body().results;
                        if (results != null) {
                            currentPage = 2;
                            newsAdapter.setNewData(results);
                        }
                    }

                    @Override
                    public void onCacheSuccess(Response<GankResponse<List<GankModel>>> response) {
                        //一般来说,只需呀第一次初始化界面的时候需要使用缓存刷新界面,以后不需要,所以用一个变量标识
                        if (!isInitCache) {
                            //一般来说,缓存回调成功和网络回调成功做的事情是一样的,所以这里直接回调onSuccess
                            onSuccess(response);
                            isInitCache = true;
                        }
                    }

                    @Override
                    public void onError(Response<GankResponse<List<GankModel>>> response) {
                        //网络请求失败的回调,一般会弹个Toast
                        showToast(response.getException().getMessage());
                    }

                    @Override
                    public void onFinish() {
                        //可能需要移除之前添加的布局
                        newsAdapter.removeAllFooterView();
                        //最后调用结束刷新的方法
                        setRefreshing(false);
                    }
                });
    }

上拉加载:

 /** 上拉加载 */
    @Override
    public void onLoadMoreRequested() {
        OkGo.<GankResponse<List<GankModel>>>get(url + currentPage)//
                .cacheMode(CacheMode.NO_CACHE)       //上拉不需要缓存
                .execute(new NewsCallback<GankResponse<List<GankModel>>>() {
                    @Override
                    public void onSuccess(Response<GankResponse<List<GankModel>>> response) {
                        List<GankModel> results = response.body().results;
                        if (results != null && results.size() > 0) {
                            currentPage++;
                            newsAdapter.addData(results);
                        } else {
                            //显示没有更多数据
                            newsAdapter.loadComplete();
                            View noDataView = inflater.inflate(R.layout.item_no_data, (ViewGroup) recyclerView.getParent(), false);
                            newsAdapter.addFooterView(noDataView);
                        }
                    }

                    @Override
                    public void onError(Response<GankResponse<List<GankModel>>> response) {
                        //显示数据加载失败,点击重试
                        newsAdapter.showLoadMoreFailedView();
                        //网络请求失败的回调,一般会弹个Toast
                        showToast(response.getException().getMessage());
                    }
                });
    }

2.5 post请求

/**
   * post请求
   * @param url
   */
  private void postByOkGo(String url){
      OkGo.post(url)
              .tag(this)
              .cacheKey("cachePostKey")
              .cacheMode(CacheMode.DEFAULT)
              .params("method", "album.item.get")
              .params("appKey", "myKey")
              .params("format", "json")
              .params("albumId", "Lqfme5hSolM")
              .params("pageNo", "1")
              .params("pageSize", "2")
              .execute(new StringCallback() {
                  @Override
                  public void onSuccess(String s, Call call, Response response) {
                      mTextView2.setText(s);
                  }

                  @Override
                  public void onError(Call call, Response response, Exception e) {
                      super.onError(call, response, e);
                      mTextView2.setText(e.getMessage());
                  }
              });
  }

2.6 文件下载

FileCallback具有三个重载的构造方法,分别是

  • FileCallback():空参构造
  • FileCallback(String destFileName):可以额外指定文件下载完成后的文件名
  • FileCallback(String destFileDir, String destFileName):可以额外指定文件的下载目录和下载完成后的文件名

注意:

文件目录如果不指定,默认下载的目录为 sdcard/download/,文件名如果不指定,则按照以下规则命名:
1.首先检查用户是否传入了文件名,如果传入,将以用户传入的文件名命名
2.如果没有传入,那么将会检查服务端返回的响应头是否含有Content-Disposition=attachment;filename=FileName.txt该种形式的响应头,如果有,则按照该响应头中指定的文件名命名文件,如FileName.txt
3.如果上述响应头不存在,则检查下载的文件url,例如:http://image.baidu.com/abc.jpg,那么将会自动以abc.jpg命名文件
4.如果url也把文件名解析不出来,那么最终将以”unknownfile_” + System.currentTimeMillis()命名文件

/**
 * 下载文件
 * @param url 下载地址
 * @param destFileDir 保存文件路径
 * @param destFileName 保存文件名
 */
private void downLoad(String url, String destFileDir, String destFileName){
    OkGo.get(url)//
            .tag(this)//
            .execute(new FileCallback(destFileDir, destFileName) {  //文件下载时,可以指定下载的文件目录和文件名
                @Override
                public void onSuccess(File file, Call call, Response response) {
                    // file 即为文件数据,文件保存在指定目录
                }

                @Override
                public void downloadProgress(long currentSize, long totalSize, float progress, long networkSpeed) {
                    //这里回调下载进度(该回调在主线程,可以直接更新ui)
                    //currentSize totalSize以字节byte为单位
                }
            });
}

2.7.上传String类型和json类型的文本

/**
* 文本上传

*/
private void uploadtexts(){
  OkGo.post(url)//
          .tag(this)//
          .upstring("这里是要上传的文本")
        //  .upjson(jsonobject)    上传json数据
        
          .execute(new StringCallback() {
              @Override
              public void onSuccess(String s, Call call, Response response) {
                  //上传成功
                  Toast.makeText(getApplicationContext(), "上传成功", Toast.LENGTH_SHORT).show();
              }

              @Override
              public void upProgress(long currentSize, long totalSize, float progress, long networkSpeed) {
                  //这里回调上传进度(该回调在主线程,可以直接更新ui)
                  mProgressBar.setProgress((int) (100 * progress));
                  mTextView2.setText("已上传" + currentSize/1024/1024 + "MB, 共" + totalSize/1024/1024 + "MB;");
              }
          });
}

2.8 上传文件

/**
* 多文件上传
* @param url
* @param keyName
* @param files 文件集合
*/
private void uploadFiles(String url, String keyName, List<File> files){
  OkGo.post(url)//
          .tag(this)//
          //.isMultipart(true)       // 强制使用 multipart/form-data 表单上传(只是演示,不需要的话不要设置。默认就是false)
          //.params("param1", "paramValue1")        // 这里可以上传参数
          //.params("file1", new File("filepath1"))   // 可以添加文件上传
          //.params("file2", new File("filepath2"))     // 支持多文件同时添加上传
          .addFileParams(keyName, files)    // 这里支持一个key传多个文件
          .execute(new StringCallback() {
              @Override
              public void onSuccess(String s, Call call, Response response) {
                  //上传成功
                  Toast.makeText(getApplicationContext(), "上传成功", Toast.LENGTH_SHORT).show();
              }

              @Override
              public void upProgress(long currentSize, long totalSize, float progress, long networkSpeed) {
                  //这里回调上传进度(该回调在主线程,可以直接更新ui)
                  mProgressBar.setProgress((int) (100 * progress));
                  mTextView2.setText("已上传" + currentSize/1024/1024 + "MB, 共" + totalSize/1024/1024 + "MB;");
              }
          });
}

2.9 请求加载图片

/**
 * 请求网络图片
 * @param url
 */
private void getBitmap(String url) {
    OkGo.get(url)//
            .tag(this)//
            .execute(new BitmapCallback() {
                @Override
                public void onSuccess(Bitmap bitmap, Call call, Response response) {
                    // bitmap 即为返回的图片数据
                    mImageView.setImageBitmap(bitmap);
                }
            });
}

2.10 取消请求

每个请求前都设置了一个参数tag,取消则通过OkGo.cancel(tag)执行。 例如:在Activity中,当Activity销毁取消请求,可以在onDestory里面统一取消;

@Override
protected void onDestroy() {
    super.onDestroy();

    //根据 Tag 取消请求
    OkGo.getInstance().cancelTag(this);

    //取消所有请求
    OkGo.getInstance().cancelAll();
}

参考链接:(OkGo的详解)
https://github.com/jeasonlzy/okhttp-OkGo/wiki/OkGo#okgo主要功能

今天的文章OkGo的详解_okr什么意思简单来说[通俗易懂]分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/71554.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注