OkHttp与Retrofit的做用和联系

1、OkHttp

一、OkHttp的介绍

OkHttp是一个关于网络请求的第三方类库,其中封装了网络请求的get、post等操做的底层实现,是Android端目前最为火热的网络请求框架之一。java

二、OkHttp的使用

在Android Studio中不须要下载专门的jar包,直接在gradle中添加依赖,以下所示:bash

compile 'com.squareup.okhttp3:okhttp:3.10.0'
复制代码

三、get方法请求

  • 同步请求 同步请求须要在子线程中执行,而且在执行结果返回后在UI线程中修改UI。下面是一个get请求的代码例子:
new Thread(new Runnable() {
    @Override
    public void run() {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url("http:www.taobao.com").build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                Log.d("ABC", "response=" + response.body().toString());
                // 转到UI线程去修改UI
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();
复制代码

get同步请求分为三步: 首先使用new建立OkHttpClient对象。 而后调用OkHttpClient对象的newCall方法生成一个Call对象,该方法接收一个Request对象,Request对象存储的就是咱们的请求URL和请求参数。 最后执行Call对象的execute方法,获得Response对象,这个Response对象就是返回的结果。服务器

  • 异步请求 异步方法不须要开启一个线程执行操做,可是要注意的是最终的回调方法是在子线程执行的,因此咱们要修改UI也必需要在UI线程中进行修改。看一下下面这个例子:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http://www.tabao.com").build();
client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Log.d("ABC", "error");
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (response.isSuccessful()) {
            Log.d("ABC", "response=" + response.body().toString());
            // 转到UI线程去修改UI
        }
    }
});
复制代码

get异步请求分为三步: 首先使用new建立OkHttpClient对象。 而后调用OkHttpClient对象的newCall方法生成一个Call对象,该方法接收一个Request对象,Request对象存储的是咱们的请求URL和请求参数。 最后执行Call对象的enqueue方法,该方法接收一个Callback回调对象,在回调对象的onResponse方法中拿到Response对象,这就是返回的结果。网络

总结:get的同步方法和异步方法的差异在于同步方法须要手动开启一个线程执行,而异步方法不须要(实际上是使用了内部的线程)。框架

四、post方法请求

  • 同步请求 post方法的同步请求和get方法的同步请求几乎是同样的,看下面的例子,并和上面的get的同步请求进行对比:
new Thread(new Runnable() {
    @Override
    public void run() {
        OkHttpClient client = new OkHttpClient();
        FormBody.Builder formBody = new FormBody.Builder();
        formBody.add("bookName", "Android Art");
        Request request = new Request.Builder().url("http:www.taobao.com").post(formBody.build()).build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                Log.d("ABC", "response=" + response.body().toString());
                // 转到UI线程去修改UI
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();
复制代码

对比:post方法的同步请求和get方法的同步请求的区别在于,post方法生成Request对象时多执行了post(RequestBody)方法,而RequestBody对象的子类是FormBody类,因此可使用FormBody对象建立键值对参数。异步

再深刻一步,为何post请求须要执行post方法,并且get请求不用呢?咱们看一下post方法里面执行了什么操做?ide

public Builder post(RequestBody body) {
    return method("POST", body);
}
复制代码

返回了method方法的执行结果,这里传递了一个“POST”字符串,看一下method方法的执行:函数

public Builder method(String method, RequestBody body) {
  if (method == null) throw new NullPointerException("method == null");
  if (method.length() == 0) throw new IllegalArgumentException("method.length() == 0");
  if (body != null && !HttpMethod.permitsRequestBody(method)) {
    throw new IllegalArgumentException("method " + method + " must not have a request body.");
  }
  if (body == null && HttpMethod.requiresRequestBody(method)) {
    throw new IllegalArgumentException("method " + method + " must have a request body.");
  }
  this.method = method;
  this.body = body;
  return this;
}
复制代码

这里将“POST"字符串传递给了Builder对象的method变量,而Builder的默认构造函数中将method变量赋值为"GET"。到这里就水落石出了,原来Request.Builder对象建立时,默认就是get请求,因此get请求就不用设置get方法了,而post请求则须要修改method变量的值为"POST"。post

  • 异步请求 post方法的异步请求和get方法的异步请求也是很是类似的,区别也是同步请求的区别,因此直接看例子吧:
OkHttpClient client = new OkHttpClient();
FormBody.Builder formBody = new FormBody.Builder();
formBody.add("bookName", "Android Art");
Request request = new Request.Builder().url("http://www.tabao.com").post(formBody.build()).build();
client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Log.d("ABC", "error");
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (response.isSuccessful()) {
            Log.d("ABC", "response=" + response.body().toString());
            // 转到UI线程去修改UI
        }
    }
});
复制代码

2、Retrofit

一、Retrofit的介绍

Retrofit是一个RESTful的HTTP网络请求框架,它是基于OkHttp的。它是经过注解配置网络参数的,支持多种数据的解析和序列化(Gson、Json、Xml等,而且对RxJava也是支持的。下面是Retrofit和OkHttp的联系图(图来自于https://blog.csdn.net/carson_ho/article/details/73732076): gradle

Retrofit和OkHttp的联系
能够看到App应用层是经过Retrofit请求网络,而后使用Retrofit接口层封装请求参数、Header、URL等信息,而后由OkHttp完成后续的和服务器的交互。 而服务器返回响应数据后,也是先返回给OkHttp,而后OkHttp将原始结果返回给Retrofit,Retrofit根据用户的需求对原始数据进行解析封装,并返回给App应用层。

二、Retrofit的使用

2.1 添加依赖库

在Android Studio中Retrofit库的依赖,因为其还依赖了OkHttp库,因此同时须要添加OkHttp的依赖。

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.okhttp3:okhttp:3.8.1'
复制代码

2.2 添加网络请求的接口

Retrofit使用注解的方式描述和配置网络请求参数。其实是运用动态代理的方式将注解翻译成一个Http请求,而后执行该请求。基本的结构以下:

public interface GitHubService {
  @GET("getUserData")
  Call<User> getCall();
}
复制代码

User.java

public class User {
    private int userId;
    private String userName;
    private ExInfo exInfo;

    private static class ExInfo {
        private String from;
        private String birthDay;
    }

    public void show() {
        Log.d("ABC", "userId=" + userId);
        Log.d("ABC", "userName=" + userName);
        Log.d("ABC", "from=" + exInfo.from);
        Log.d("ABC", "birthday=" + exInfo.birthDay);
    }
}
复制代码

注意项: 一、这是一个接口(Interface)不是一个类(class)。 二、其中能够建立不一样的接口方法。 三、每个接口方法和接口方法的参数必须使用注解的方式标注,不然会报错。 四、请求方法有GET、POST、PUT、HEAD、DELETE等。 五、方法的返回类型必须为Call,xxx是接收数据的类(能够是咱们自定义的类,也能够是ResponseBody)。 六、User中字段的名字必须和后台Json定义的字段名是一致的,这样Json才能解析成功。

2.3 建立Retrofit对象

Retrofit retrofit = new Retrofit.Builder().baseUrl("http://10.75.114.138:8081/")
                .addConverterFactory(GsonConverterFactory.create()).build(); //设置网络请求的Url地址
                .addConverterFactory(GsonConverterFactory.create()) //设置数据解析器
                .build();
复制代码

网络请求的地址:建立Retrofit对象时经过baseUrl()设置+网络请求接口的注解设置。 addConverterFactory(GsonConverterFactory.create())的做用是设置数据解析器,它能够解析Gson、JsonObject、JsonArray这三种格式的数据。

2.4 建立网络请求接口实例

// 建立 网络请求接口 的实例
GitHubServiceRequest request = retrofit.create(GitHubService.class);

//对 发送请求 进行封装
Call<Reception> call = request.getCall();
复制代码

2.5 发送网络请求

同步请求:

// 发送网络请求(同步)
Response<Reception> response = call.execute();
复制代码

异步请求:

call.enqueue(new Callback<User>() {
    //请求成功后回调
    @Override
    public void onResponse(Call<User> call, Response<User> response) {
        //处理请求结果
        User user = response.body();
        if(user != null) {
            user.show();
        }
    }

    //请求失败后回调
    @Override
    public void onFailure(Call<User> call, Throwable throwable) {
        System.out.println("请求失败");
    }
});
复制代码

三、总结

Retrofit的一个RESTful风格的网络请求框架,其下一层的实现也是OkHttp,因此其原理和OkHttp的同样的,只是在OkHttp的上面封装了一层,使请求接口和数据解析更加简洁明了。

相关文章
相关标签/搜索