网络请求——OkHttp3的简单使用

        我们敲代码总是离不开网络请求。网络请求就是想服务器请求数据,一般请求到的数据就是我们列表上要展示数据的数据源。现在最长用的就是OkHttp、Volley、Retrofit2了。现在我们先说说OkHttp

       想要使用OkHttp需要导入OkHttp的第三方依赖:

   implementation 'com.squareup.okhttp3:okhttp:3.10.0'

注意:如果你的Android Studio是3.0以下的版本要讲"implementation"改为"compile"。

导入依赖以后我们才能开始使用OkHttp。

1)我们需要创建OKHttpClient对象,OkHttpClient对象有2种方式创建:

        1:通过new关键字直接创建

                OkHttpClient okHttpClient =new OkHttpClient();

        2:通过构建者模式创建OkHttpClient的内部类Builder对象来获取OKHttpClient

                OkHttpClient okHttpClient = new OkHttpClient.Builder().build();

    我们常用第2种方法创建OkHttpClient对象。可以给OkHttpClient对象添加拦截器对象,而且构建者模式创建OkHttpClient对象代码看起来非常整洁。

        添加拦截器对象

        添加应用拦截器对象addInterceptor(Interceptor interceptor),添加网络拦截器对象addNetworkInterceptor(Interceptor interceptor)这个拦截器对象稍后再说。

2)创建Request对象

        这里我们不能直接通过new创建Request对象。因为Request的构造方法不是公共的,但是我们可以通过创建Request的内部类对象获取Request。

    Request request =new Request.Builder().build();

在创建Request对象时可以配置url地址,请求方式、请求头

    配置url地址:

        Request request =new Request.Builder().url(String url).build();

配置其他方式一样在Builder()后直接打“.”调用就好了,我就直接贴方法了 。

    设置请求方式:

        1、get请求

            get()        //Request.Builder的方法

get请求可以不设置,默认就为get请求,你不需要再手动去设置请求方式。

    2、post请求

            post(RequestBody requestBody)        //Request.Builder的方法

    RequestBody该类是一个接口我们通常传入它的子类FormBody。

            创建FormBody对象,和Request一样该类的构造方法不是公共的通过创建FormBody的内部类对象获取FormBody。

        FormBody formBody =new FormBody.Builder().build();

post请求一般都有参数,如果post请求没有参数我们可以直接当做get请求来请求就OK了。那么post请求的参数在哪添加呢?在FormBody中添加通过add(String name,String value)添加参数信息。

    添加请求头:

        addHeader(String name,String value)        //Request.Builder的方法

3)通过OkHttpClient对象发起请求

通过OkHttpClient的newCall(Requset request)方法返回Call对象。Call对象才是网络请求的真正执行者。

    Call call =okHttpClient.newCall(request);

请求方式有2种:

    1:同步请求

        在发出同步请求后该线程会进入阻塞状态,等待请求完成在会继续往下执行。但是在Android中我们不能阻塞UI线程也就是主线程,如果主线程阻塞则程序直接挂掉。也就是我们常说的ANR异常。所有在用同步请求时要开一个子线程去请求数据。

Request request =new Request.Builder()

        //设置url地址

        .url(url).build();

        //获取Call对象

        Call call =okHttpClient.newCall(request);

        try {

                //发送同步请求

                Response response = call.execute();

                //将结果转为String

                String responseStr = response.body().string();

          }catch (IOException e) {

                e.printStackTrace();

         }

    2:异步请求

        在发出异步请求后OkHttp内部会开启一个线程去请求数据,数据请求完成之后会通过接口回调的方式来存储数据。主线程不会阻塞,但是以后相关的操作都要在数据回来的时候书写。

        Request request =new Request.Builder()

        //设置url地址

        .url(url).build();

        //获取Call对象

        Call call =okHttpClient.newCall(request);

        //发送异步请求

        call.enqueue(new Callback() {

            /*

                在这个内部类的方法都是在子线程中,如果你需要更新UI的就要做线程之间的切换

            */

            /**

            * 请求失败的监听

            * @param call

            * @param e 失败的错误信息

            */

            @Override

            public void onFailure(Call call,final IOException e) {

                    //切换回主线程循环执行

                    runOnUiThread(new Runnable() {

                            @Override

                            public void run() {

                                        Toast.makeText(MainActivity.this,"错误信息 : " +e.getMessage(), Toast.LENGTH_SHORT).show();

                            }

                    });

            }

            /**

              * 请求成功的监听

              * @param call

              * @param response  请求结果

              * @throws IOException

            */

            @Override

            public void onResponse(Call call, Response response)throws IOException {

                    //获取请求体对象

                    ResponseBody responseBody = response.body();

                    //将请求结果转化为字符串

                    final String responseStr = responseBody.string();

                    /*

                            拿到数据之后,Gson解析数据

                    */

                    //切换回主线程循环执行

                    runOnUiThread(new Runnable() {

                            @Override

                            public void run() {

                                        Toast.makeText(MainActivity.this,"请求结果 : " +responseStr, Toast.LENGTH_SHORT).show();

                            }

                    });

            }

    });

到这里你就可以使用OkHttp来做一些简单的网络请求了。

下面说说给Okhttp配置拦截器:

有时候我们需要添加响应头信息、拦截响应头。在我们实际开发的过程中于后台联调也是通过拦截器来进行的。拦截器怎么重要,该怎么使用呢?

拦截器分两种

    1.应用拦截器

          addInterceptor(Interceptor interceptor)        //OkHttpClient.Builder的方法

      应用拦截器也叫日志拦截器。可以自己手动写应用拦截器,也可以导入依赖用Okhttp提供的应用拦截器

            1).手动写拦截器

                //创建拦截器对象

                Interceptor interceptor =new Interceptor() {

                @Override

                public Response intercept(Chain chain)throws IOException {

                        //获取请求对象

                        Request request = chain.request();

                        //获取响应对象

                        Response response = chain.proceed(request);

                        //获取所有响应头

                        Headers headers = response.headers();

                        //便利所有响应头

                        Set names = headers.names();

                        for (String name : names) {

                                Log.d("OkHttpUtils", name +" : " + headers.get(name));

                        }

                        //一定要将原有响应对象返回,不要去new。否则请求不到数据

                        return response;

                }

        };

            2).导入依赖实现拦截器

                    implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'

                         //创建拦截器对象

                        HttpLoggingInterceptor interceptor =new HttpLoggingInterceptor(HttpLoggingInterceptor.Logger.DEFAULT);

                        //设置打印信息    HEADERS为响应头  BODY为响应体  NONE为什么都不打印  BASIC为基本信息(响应头和响应体)

                        interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);

 2.网络拦截器

        addNetworkInterceptor(Interceptor interceptor)          //OkHttpClient.Builder的方法

网络拦截器通常用于添加响应头,和拦截响应头时使用,比如设置缓存。网络拦截器只能手动书写,没有可导入的依赖。

            Interceptor interceptor =new Interceptor() {

                    @Override

                    public Response intercept(Chain chain)throws IOException {

                            //获取请求对象

                            Request request = chain.request();

                            //获取响应对象

                            Response response = chain.proceed(request);

                            //通过原有的Response对象获取 Response.Builder

                            Response.Builder responseBuilder = response.newBuilder();

                            //添加响应头

                            Response newResponse = responseBuilder

                                        .addHeader("key","value")

                                        .addHeader("key2","value2").build();

                            //将新获取的Response对象返回

                            return newResponse;

                    }

            };

最后说说设置缓存

我们做的网络请求,通常都会缓存数据。这样会给用户节约流量。

        cache(Cache cache)          //OkHttpClient.Builder的方法

缓存分两种情况:

        1).后台服务器支持缓存

                如果后台服务器支持缓存(响应头中有"Cache-Control"字段),直接设置存储地址与文件大小即可。

                            //创建Cache对象 App.context.getCacheDir()获取App的dir目录 文件大小

                            Cache cache =new Cache(App.context.getCacheDir(),1024 *1024 *10);

        2).后台服务器不支持缓存

                如果后台服务器不支持缓存(响应头中没有"Cache-Control"字段)。需要拦截响应头,手动添加"Cache-Control"字段,在设置存储地址与文件大小。

        1.手动添加"Cache-Control"字段

                        Interceptorinterceptor =new Interceptor() {

                                    @Override

                                    public Response intercept(Chain chain)throws IOException {

                                            //获取请求对象

                                            Request request = chain.request();

                                            //获取响应对象

                                            Response response = chain.proceed(request);

                                            //通过原有的Response对象获取 Response.Builder

                                            Response.Builder responseBuilder = response.newBuilder();

                                            //添加响应头

                                            Response newResponse = responseBuilder

                                            //添加Cache-Control字段支持缓存

                                            .addHeader("Cache-Control","max-age=" +60 *60 *12)

                                            .build();

                                            //将新获取的Response对象返回

                                            return newResponse;

                                    }

                            };

        2.设置存储地址与文件大小。

                          //创建Cache对象 App.context.getCacheDir()获取App的dir目录 文件大小

                            Cache cache =new Cache(App.context.getCacheDir(),1024 *1024 *10);

GetHub源码地址:https://github.com/AndroidHMH/OkHttpDemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • 6.1 公钥密钥加密原理 6.1.1 基础知识 密钥:一般就是一个字符串或数字,在加密或者解密时传递给加密/解密算...
    AndroidMaster阅读 4,006评论 1 8
  • 有兴趣可以关注weixin公众号 [丰收笔记]获取股市牛股最新动向,另附送免费诊股。 关口震荡 高抛低吸 周四大盘...
    虔诚o阅读 84评论 0 0
  • 医生让休假两周,但是因为怕扣工资,乖乖提前回去上班,这就是现实的无奈。 向往自由,却没有承载得起自由的物质条件和现...
    倩姐姐的圈圈儿阅读 573评论 0 50
  • 一款法律咨询交流服务类app。通过在线方式,实现用户与律师零距离问答 ◆产品简介通过在线方式,实现用户与律师零距离...
    piegroups阅读 248评论 0 1