网络请求——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

你可能感兴趣的:(网络请求——OkHttp3的简单使用)