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的上面封裝了一層,使請求接口和數據解析更加簡潔明瞭。

相關文章
相關標籤/搜索