美文网首页
okHttp源码解析(一)— okHttp的使用

okHttp源码解析(一)— okHttp的使用

作者: 贝贝ovo | 来源:发表于2019-05-23 22:39 被阅读0次

okhttp的使用

主要三个步骤:

1.创建OkHttpClient实例
2.使用构造器创建请求
3.提交请求

概括为

  OkHttpClient client = new OkHttpClient();//1.
  Request request = new Request.Builder()
      .url(url)
      .build();//2.
  Response response = client.newCall(request).execute();//3. enqueue()异步

下面是具体的几种使用方式

Get 同步请求
Get 异步请求
Post 异步请求
Post 异步请求——使用RequestBody传递Json或File对象
Post 异步请求——使用MultipartBody同时传递键值对参数和File对象
Post 异步请求——自定义一个类,继承RequestBody,实现流的上传
Post 异步请求——下载文件


  • Get 同步请求
    public void getDataSync(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient okHttpClient = new OkHttpClient();//1.
                Request request = new Request.Builder()
                        .url("http://www.baidu.com")
                        .build();//2.
                try {
                    Response response = okHttpClient.newCall(request).execute();//3.
                    if(response.isSuccessful()){
                        //此时的代码执行在子线程,修改UI的操作请使用handler跳转到UI线程。
                        Log.d(TAG,"response.code()=="+response.code());
                        Log.d(TAG,"response.message()=="+response.message());
                        Log.d(TAG,"res=="+response.body().string());
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
  • Get 异步请求
   public void getDataAsync(){
       OkHttpClient okHttpClient = new OkHttpClient();//1.

       Request request = new Request.Builder()
               .url("http://www.baidu.com")
               .build();//2.
       okHttpClient.newCall(request).enqueue(new Callback() {//3.
           @Override
           public void onFailure(Call call, IOException e) {}

           @Override
           public void onResponse(Call call, Response response) throws IOException {
               //回调的方法执行在子线程。
               if(response.isSuccessful()){
                   Log.d(TAG,"response.code()=="+response.code());
                   Log.d(TAG,"response.body().string()=="+response.body().string());
               }
           }
       });
   }
  • Post 异步请求
    public void postDataWithParames(){
        OkHttpClient okHttpClient = new OkHttpClient();//1.
        //创建表单请求体
        FormBody formBody = new FormBody.Builder()
                .add("userName", "beibei")
                .build();

        Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .post(formBody)  //FormBody extends RequestBody
                .build();

        okHttpClient.newCall(request).enqueue(new Callback() {//3.
            @Override
            public void onFailure(Call call, IOException e) {}

            @Override
            public void onResponse(Call call, Response response) throws IOException {}
        });
    }
  • Post 异步请求——使用RequestBody传递Json或File对象
    public void postJson(){
        OkHttpClient okHttpClient = new OkHttpClient();//1.

        MediaType JSON = MediaType.parse("application/json;charset=utf-8");
        String jsonStr = "{\"username\":\"lisi\"}";
        RequestBody requestBody = RequestBody.create(JSON, jsonStr);

        Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .post(requestBody)
                .build();//2.
        okHttpClient.newCall(request).enqueue(new Callback() {//3.
            @Override
            public void onFailure(Call call, IOException e) {}

            @Override
            public void onResponse(Call call, Response response) throws IOException {}
        });
    }
    public  void  postFile(){
        OkHttpClient okHttpClient = new OkHttpClient();//1.

        MediaType fileType = MediaType.parse("File/*");
        File file = new File("path");
        RequestBody requestBody = RequestBody.create(fileType, file);

        Request request = new Request.Builder()
                .url("http://www/baidu.com")
                .post(requestBody)
                .build();//2.
        okHttpClient.newCall(request).enqueue(new Callback() {//3.
            @Override
            public void onFailure(Call call, IOException e) {}

            @Override
            public void onResponse(Call call, Response response) throws IOException {}
        });
    }
  • Post 异步请求——使用MultipartBody同时传递键值对参数和File对象
    /**
     * 使用MultipartBody同时传递键值对参数和File对象
     *
     * FromBody传递的是字符串型的键值对,RequestBody传递的是多媒体,那么如果我们想二者都传递怎么办?此时就需要使用MultipartBody类。
     */
    public void postMultipart(){
        OkHttpClient okHttpClient = new OkHttpClient();//1.

        File file = new File("path");
        MultipartBody multipartBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("groupId", "1")
                .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("file/*"), file))
                .build();
        Request request = new Request.Builder()
                .url("URLContant.CHAT_ROOM_SUBJECT_IMAGE")
                .post(multipartBody)//MultipartBody extends RequestBody
                .build();//2.

        okHttpClient.newCall(request).enqueue(new Callback() {//3.
            @Override
            public void onFailure(Call call, IOException e) {}

            @Override
            public void onResponse(Call call, Response response) throws IOException {}
        });
    }
  • Post 异步请求—— 自定义一个类,继承RequestBody,实现流的上传
    public void customRequestBody(){
        RequestBody body = new RequestBody() {
            @Override
            public MediaType contentType() {
                return null;
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                FileInputStream fio = new FileInputStream(new File("fileName"));
                byte[] buffer = new byte[1024 * 8];
                if (fio.read(buffer) != -1) {
                    sink.write(buffer);
                }
            }
        };
        
        OkHttpClient client = new OkHttpClient();//1.
        
        Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .post(body)
                .build();//2.
        
        client.newCall(request).enqueue(new Callback() {//3.
            @Override
            public void onFailure(Call call, IOException e) {}

            @Override
            public void onResponse(Call call, Response response) throws IOException {}
        });
    }
  • Post 异步请求—— 下载文件
    public void postDownLoad(){
        OkHttpClient okHttpClient = new OkHttpClient();//1.
        //创建表单请求体
         FormBody formBody = new FormBody.Builder()
                .add("userName", "beibei")
                .build()

        Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .post(formBody)
                .build();//2.

        okHttpClient.newCall(request).enqueue(new Callback() {//3.
            @Override
            public void onFailure(Call call, IOException e) {}

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //从服务器得到输入流对象
                InputStream inputStream = response.body().byteStream();
                long sum = 0;
                File fileDir = new File("mDestFileDir");
                if(!fileDir.exists()){
                    fileDir.exists();
                }
                File file = new File(fileDir, "mDestFileName");

                FileOutputStream fos = new FileOutputStream(file);
                byte[] buf = new byte[1024 * 8];
                int len = 0;
                while ((len = inputStream.read(buf))!=-1){
                    fos.write(buf,0,len);
                }
                fos.flush();
//                return file;
            }
        });
    }

主要类的介绍

1、OKHttpClient类详解

  • 1、里面包含了很多对象,其实OKhttp的很多功能模块都包装进这个类,让这个类单独提供对外的API,这种外观模式的设计十分的优雅。外观模式
  • 2、而内部模块比较多,就使用了Builder模式(建造器模式)。Builder模式(建造器模式)
  • 3、它常用的一个方法:newCall。返回一个Call对象(一个准备好了的可以执行和取消的请求)。

使用时,在构造了OKHttpClient后,又new了一个Rquest对象。那么咱们就来看下Request,说道Request又不得不提Response。所以咱们一起讲了

2、Request、Response类详解

  • 1、Request、Response分别抽象成请求和响应
  • 2、其中Request包括HeadersRequestBody,而RequestBody是abstract的,他的子类是有FormBody (表单提交)和 MultipartBody(文件上传),分别对应了两种不同的MIME类型
    FormBody :"application/x-www-form-urlencoded"
    MultipartBody:"multipart/"+xxx.
  • 3、其中Response包括 HeadersResponseBody,而ResponseBody是abstract的,他的子类也是有两个:RealResponseBodyCacheResponseBody,分别代表真实响应和缓存响应。
  • 4、由于RFC协议规定,所以所有的头部信息不是随便写的,request的header与response的header的标准都不同。具体的见 List of HTTP header fields。OKHttp的封装类Request和Response为了应用程序编程方便,会把一些常用的Header信息专门提取出来,作为局部变量。比如contentType,contentLength,code,message,cacheControl,tag...它们其实都是以name-value对的形式,存储在网络请求的头部信息中。

使用时,用builder构建了Request对象,然后执行OKHttpClient.的newCall方法,看下newCall里面都做什么操作

 /**
   * Prepares the {@code request} to be executed at some point in the future.
   */
  @Override public Call newCall(Request request) {
    return RealCall.newRealCall(this, request, false /* for web socket */);
  }

Call是个什么东西,那咱们看下Call这个类

3、Call类详解
Call: HTTP请求任务封装
可以说我们能用到的操纵基本上都定义在这个接口里面了,所以也可以说这个类是OKHttp类的核心类了。
我们可以通过Call对象来操作请求了。而Call接口内部提供了Factory工厂方法模式(将对象的创建延迟到工厂类的子类去进行,从而实现动态配置)

Call接口
在源码中,OKHttpClient实现了Call.Factory接口,返回了一个RealCall对象。那我们就来看下RealCall这个类

相关文章

网友评论

      本文标题:okHttp源码解析(一)— okHttp的使用

      本文链接:https://www.haomeiwen.com/subject/upwpzqtx.html