OkGo___简单易用的OkHttp网络请求封装库

引入

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

初始化

//没有特殊需要的话,最简单的初始化就可以了
OkGO.getInstance()
    .init(application); 
//定制
        //设置全局请求头,不支持中文,不允许有中文字符
        HttpHeaders headers = new HttpHeaders();
        headers.put("commonHeaderKey1", "commonHeaderValue1");
        headers.put("commonHeaderKey2", "commonHeaderValue2");

        //设置全局请求参数,支持中文
        HttpParams params = new HttpParams();
        params.put("commonParamsKey1", "commonParamsValue1");
        params.put("commonParamsKey2", "这里支持中文参数");

        //使用OkGo的拦截器
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("meee");
        //日志的打印范围
        loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);
        //在logcat中的颜色
        loggingInterceptor.setColorLevel(Level.INFO);
        //默认是Debug日志类型
        builder.addInterceptor(loggingInterceptor);

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

        //okhttp默认不保存cookes/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,退出后失效

        OkGo.getInstance()
                .init(this)
                .setOkHttpClient(builder.build())//不设置则使用默认
                .setCacheMode(CacheMode.NO_CACHE)//设置缓存模式
                .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)//设置缓存时间,默认永不过期
                .setRetryCount(3);//请求超时重连次数,默认3次
//                .addCommonHeaders(headers)
//                .addCommonParams(params);

基本使用

get请求

        OkGo.<String>get("url")//
                .tag(this)
                .params("adKind","1")//传入请求参数
                .cacheKey("cachekey")//作为缓存的key
                .cacheMode(CacheMode.NO_CACHE)//设置缓存模式

                //StringCallback只返回成功
                .execute(new StringCallback() {
                    @Override
                    public void onSuccess(Response<String> response) {

                    }
                    @Override//适配器模式,可以不实现该方法
                    public void onError(Response<String> response) {

                    }
                });

Post请求

                OkGo.<LzyResponse<ServerModel>>post(Urls.URL_METHOD)//
                        .tag(this)//
                        .headers("header1", "headerValue1")//
                        .params("param1", "paramValue1")//
                        .params("param2", "paramValue2")//
                        .params("param3", "paramValue3")//
                        .isMultipart(true)         //强制使用 multipart/form-data 表单上传(只是演示,不需要的话不要设置。默认就是false)
                        .execute(new DialogCallback<LzyResponse<ServerModel>>(this) {
                            @Override
                            public void onSuccess(Response<LzyResponse<ServerModel>> response) {
                                handleResponse(response);
                            }

                            @Override
                            public void onError(Response<LzyResponse<ServerModel>> response) {
                                handleError(response);
                            }
                        });

下载图片

        OkGo.<Bitmap>get(url)
                .execute(new BitmapCallback() {
                    @Override
                    public void onSuccess(Response<Bitmap> response) {
                        Log.d("meee", getClass() + ":\n" + "onSuccess:" + response.body().getHeight());
                        iv.setImageBitmap(response.body());
                    }
                });

下载文件

        OkGo.<File>get("http://url.9xiazaiqi.com/down/苍之纪元-电脑版@295_21797.exe")
                .execute(new FileCallback(/*可以传入路径和名称*/) {
                    @Override
                    public void onSuccess(Response<File> response) {
                        Log.d("meee",getClass()+":\n"+"test:"+(response.body().length()/1024)+"KB");
                    }

                    //progress.fraction获取当前的下载进度
                    @Override
                    public void downloadProgress(Progress progress) {
                        Log.d("meee",getClass()+":\n"+"progress:"+progress.fraction);
                    }
                });

上传String文本

一般此种用法用于与服务器约定的数据格式,当使用该方法时,params中的参数设置是无效的,所有参数均需要通过需要上传的文本中指定,此外,额外指定的header参数仍然保持有效。

默认会携带以下请求头

Content-Type: text/plain;charset=utf-8
如果你对请求头有自己的要求,可以使用这个重载的形式,传入自定义的content-type

// 比如上传xml数据,这里就可以自己指定请求头 upString("这是要上传的长文本数据!", MediaType.parse("application/xml"))

这里写图片描述

基本断点续传

上传文件

上传文件支持文件与参数一起同时上传,也支持一个key上传多个文件,以下方式可以任选

特别要注意的是

1). 很多人会说需要在上传文件到时候,要把Content-Type修改掉,变成multipart/form-data,就像下面这样的。其实在使用OkGo的时候,只要你添加了文件,这里的的Content-Type不需要你手动设置,OkGo自动添加该请求头,同时,OkGo也不允许你修改该请求头。

Content-Type: multipart/form-data; boundary=f6b76bad-0345-4337-b7d8-b362cb1f9949
2). 如果没有文件,那么OkGo将自动使用以下请求头,同样OkGo也不允许你修改该请求头。

Content-Type: application/x-www-form-urlencoded

3). 如果你的服务器希望你在没有文件的时候依然使用multipart/form-data请求,那么可以使用.isMultipart(true)这个方法强制修改,一般来说是不需要强制的。

这里写图片描述
这里写图片描述

取消请求

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //取消指定tag的请求
        OkGo.getInstance().cancelTag(this);
        //取消全部请求
        OkGo.getInstance().cancelAll();
        //取消OkHttpClient的全部请求
        OkGo.cancelAll(new OkHttpClient());
        OkGo.cancelTag(new OkHttpClient(),"且指定tag");
    }

同步请求

        //NetworkOnMainThreadException
        //方式一:
        try {
            okhttp3.Response response = OkGo.<String>get(url)
                    .params("adKind", "1")
                    .execute();

            Log.d("meee",getClass()+":\n"+"test:"+response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }
        //方式二,也许可以转换成Rxjava的Obser
        Call<String> call = OkGo.<String>get(url)
                .params("adKind", "1")
                .converter(new StringConvert())
                .adapt();
        try {
            Response<String> execute = call.execute();
            Log.d("meee",getClass()+":\n"+"execute:"+execute.body());
        } catch (Exception e) {
            e.printStackTrace();
            Log.d("meee",getClass()+":\n"+"Exception:");
        }
    }

Cookies管理

cookie是有作用域的,他绑定的是url对应的host,比如你的请求两个接口,一个是 www.domain1.com 一个是 www.domain2.com 那么这个时候,domain1所具有的cookie是不会自动在domain2中携带的,如果一定要让他们两个都可以用,那么需要手动设置,方法请看下面的cookie交互。

查看okgo管理的cookie中,某个url所对应的全部cookie

CookieStore cookieStore = OkGo.getInstance().getCookieJar().getCookieStore();
HttpUrl httpUrl = HttpUrl.parse("http://server.jeasonlzy.com/OkHttpUtils/method/");
List<Cookie> cookies = cookieStore.getCookie(httpUrl);
showToast(httpUrl.host() + "对应的cookie如下:" + cookies.toString());
查看okgo管理的所有cookie

CookieStore cookieStore = OkGo.getInstance().getCookieJar().getCookieStore();
List<Cookie> allCookie = cookieStore.getAllCookie();
showToast("所有cookie如下:" + allCookie.toString());
手动向okgo管理的cookie中,添加一些自己的cookie,那么以后满足条件时,okgo就会带上这些cookie

HttpUrl httpUrl = HttpUrl.parse("http://server.jeasonlzy.com/OkHttpUtils/method/");
Cookie.Builder builder = new Cookie.Builder();
Cookie cookie = builder.name("myCookieKey1").value("myCookieValue1").domain(httpUrl.host()).build();
CookieStore cookieStore = OkGo.getInstance().getCookieJar().getCookieStore();
cookieStore.saveCookie(httpUrl, cookie);
手动把okgo管理的cookie移除

HttpUrl httpUrl = HttpUrl.parse("http://server.jeasonlzy.com/OkHttpUtils/method/");
CookieStore cookieStore = OkGo.getInstance().getCookieJar().getCookieStore();
cookieStore.removeCookie(httpUrl);

支持Rxjava2

内部使用了
compile 'io.reactivex.rxjava2:rxjava:2.1.0'
但还是需要添加
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
用于切换线程
        OkGo.<String>get("url")//
                .tag(this)
                .params("adKind", "1")
                .converter(new StringConvert())
                .adapt(new ObservableResponse<String>())
                .compose(ThreadSwitch.<Response<String>>switchSchedulers())
                .subscribe(new Consumer<Response<String>>() {
                    @Override
                    public void accept(@NonNull Response<String> stringResponse) throws Exception {
                        Log.d("meee",getClass()+":\n"+"stringResponse:"+stringResponse.body());
                    }
                });

作者的convert还是太复杂了,咱们还是用普通的用Gson好了

               //解析父类泛型的真实类型(有局限性,继承后就无法解析到)
                Type genType = getClass().getGenericSuperclass();
                type = ((ParameterizedType) genType).getActualTypeArguments()[0];
//引入Gson
compile 'com.google.code.gson:gson:2.8.2'
//自定义转换器
public class JsonConvert<T> implements Converter<T> {
    Class<T> clazz;
    private static Gson mGson;
    public static Gson getGson(){
        if (mGson==null){
            synchronized (JsonConvert.class){
                if (mGson==null){
                    mGson=new Gson();
                }
            }
        }
        return mGson;
    }

    public JsonConvert(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override
    public T convertResponse(Response response) throws Throwable {
        Gson gson =getGson();
        JsonReader jsonReader = new JsonReader(response.body().charStream());
        T t = gson.fromJson(jsonReader, clazz);
        return t;
    }
}
//
        OkGo.<JsonBean>get("url")//
                .tag(this)
                .params("adKind", "1")
                //核心就是converter和adapter两个方法,之后就和普通的rxava一样了
                .converter(new JsonConvert<JsonBean>(JsonBean.class))
                .adapt(new ObservableResponse<JsonBean>())
                .compose(ThreadSwitch.<Response<JsonBean>>switchSchedulers())//封装了线程切换
                .map(new Function<Response<JsonBean>, JsonBean>() {
                    @Override
                    public JsonBean apply(@NonNull Response<JsonBean> jsonBeanResponse) throws Exception {
                        return jsonBeanResponse.body();
                    }
                })
                .subscribe(new Consumer<JsonBean>() {
                    @Override
                    public void accept(@NonNull JsonBean jsonBean) throws Exception {
                        Log.d("meee",getClass()+":\n"+"jsonBean:"+jsonBean);
                    }
                });

上传和下载的功能拓展

compile 'com.lzy.net:okserver:2.0.5'
//下载
https://github.com/jeasonlzy/okhttp-OkGo/wiki/OkDownload
//上传
https://github.com/jeasonlzy/okhttp-OkGo/wiki/OkUpload
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值