1. 程式人生 > >OKHttp的介紹和基本用法

OKHttp的介紹和基本用法

      嗨,大家好。又和大家見面了,今天我和大家一起來學習一下OKHttp。

     OKHttp是基於Http協議上的網路通訊,說白了就是Http協議。Http的功能OKHttp都有。那就問題來了,既然有了Http,這 強大的協議,為什麼還需要有OKHttp等將Http封裝的架包呢?其實程式設計是一個工作量大,工作重複性普遍的工作。程式設計人員都不喜歡做重複性的工作和處理Bug。個人感覺OKHttp就是基於這一系列的因素。所以OKHttp就誕生了。

      OkHttp由於基於Http協議,所以http協議都支援。例如請求報文,響應報文,所有的請求方法等多做了很好的的處理。所以有關Http的知識就不詳細講解了,讀者可以自己去查詢資料瞭解一下。下面介紹使用OkHttp訪問網路。

   其實使用OKHttp訪問網路很簡單,主要通過以下幾步:

   1、初始化OKHttpClient例項

   注:OKHttpClient在整個專案中使用單例模式,儘量直接new例項

//初始化OkHttpClient,OkHttpClient將採用單例模式
private static OkHttpClient okHttpClient = new OkHttpClient();
   2、初始化RequestBody例項,用於封裝請求的內容(PS:如果使用get請求可以直接省略該步驟)
//初始化RequestBody,用於儲存我訪問網路的請求資訊
RequestBody requestBody = RequestBody.create
(JSONTYPE, requestContent);
   

  3、初始化Request例項,用於封裝請求資訊

Request request = builder.url(url).build();
  4、初始化Call例項,用於訪問網路
//初始化Call物件,用於訪問網路
Call call = okHttpClient.newCall(request);

 5、訪問網路,OKhttp訪問網路提供了兩種方法

    5.1、同步方法,返回Response物件,該物件封裝了網路資源資訊

//初始化Response物件,用於顯示訪問網路的響應頭資訊
Response response = call.execute();

   5.2、非同步方法 (PS:非同步方法採用Callback介面回撥機制)

/*
* 採用非同步方法訪問網路,返回響應報文資訊* */
public void enqueue(String url, Callback callback, String requestContent) {

    if (requestContent == null || "".equals(requestContent)) {
        //採用非同步get方法訪問網路
Request request = this.getRequest(url);
//初始化Call物件,用於網路連線
Call call = okHttpClient.newCall(request);
//採用非同步訪問網路
call.enqueue(callback);
} else {
        //採用非同步post方法訪問網路
Request request = this.getRequest(url, requestContent);
//初始化Call物件,用於網路連線
Call call = okHttpClient.newCall(request);
call.enqueue(callback);
}

}

  6、通過Response獲得網路資源

//初始化ResponseBody物件,用於封裝網路資源,該實體用許多訪問網路資源的方法
ResponseBody body = response.body();
//以字串的形式獲得網路
result = body.string();
//以字元流的形式獲得網路
//body.charStream();
//以位元組的形式獲得網路
// body.bytes();
//以位元組流的形式獲得網路
//body.byteStream();
//獲得響應頭
Headers headers = response.headers();
//遍歷響應頭資訊
for (int i = 0; i < headers.size(); i++){
    Log.d("tag",headers.name(i) + "--->" + headers.value(i));
}

            通過以上的步驟就可以訪問網路了,很簡單嘛。但別以為OKHttp就只有這點功能,我這裡僅僅簡單介紹一下,幫助大家引進門,最好的學習方法就是看APi,看原始碼學習,瞭解大神的程式設計思想。

     下面我將我學習OKHttp過程編寫的工具類copy出來,提供大家學習。

/*
*
* 該工具類採用單例模式* */
public class OkHttpUtils {


    //初始化OkHttpClient,OkHttpClient將採用單例模式
private static OkHttpClient okHttpClient = new OkHttpClient();
//初始化OkHttpUtils
private static OkHttpUtils okHttpUtils = new OkHttpUtils();
//傳送請求訊息為Json型別
private static final MediaType JSONTYPE = MediaType.parse("application/*; charset=utf-8");
//構造私有的構造器,使外部不能直接建立例項
private OkHttpUtils() {

    }

    //採用單例模式中餓漢模式
public static OkHttpUtils getInstance() {
        return okHttpUtils;
}


    //採用類方法獲得單一的OkHttpClient例項
public static OkHttpClient getOkHttpClient() {
        return okHttpClient;
}


    /*
    * 獲得get方法Request的請求資訊    * */
private Request getRequest(String url) {

        return getRequest(url, null);
}


    /*
    * 獲取響應頭    * */
public void getHeader(String url) {

        getHeader(url, null);
}

    /*
    * 獲取響應頭    * */
public void getHeader(String url, String requestContent) {


        //初始化Request物件用於封裝請求訊息
Request request = this.getRequest(url, requestContent);
        try {
            //訪問網路,獲得響應資訊
Response response = this.execute(request);
//獲得響應頭
Headers headers = response.headers();
//遍歷響應頭資訊
for (int i = 0; i < headers.size(); i++){
               Log.d("tag",headers.name(i) + "--->" + headers.value(i));
}


        } catch (IOException e) {
            e.printStackTrace();
}
    }

    /*
    * call.execute()訪問網路,返回響應報文資訊    * */
private Response execute(Request request) throws IOException {
        //初始化Call物件,用於訪問網路
Call call = okHttpClient.newCall(request);
//初始化Response物件,用於顯示訪問網路的響應頭資訊
Response response = call.execute();
        return response;
}





   /*
    * 採用非同步方法訪問網路,返回響應報文資訊    * */
public void enqueue(String url, Callback callback) {


        enqueue(url, callback, null);
}


    /*
    * 採用非同步方法訪問網路,返回響應報文資訊    * */
public void enqueue(String url, Callback callback, String requestContent) {

        if (requestContent == null || "".equals(requestContent)) {
            //採用非同步get方法訪問網路
Request request = this.getRequest(url);
//初始化Call物件,用於網路連線
Call call = okHttpClient.newCall(request);
//採用非同步訪問網路
call.enqueue(callback);
} else {
            //採用非同步post方法訪問網路
Request request = this.getRequest(url, requestContent);
//初始化Call物件,用於網路連線
Call call = okHttpClient.newCall(request);
call.enqueue(callback);
}

    }


    /*
    * 獲得post方法的Request請求資訊,當requestContent資訊為null時,預設為get請求    * */
private Request getRequest(String url, String requestContent) {

        if ("".equals(requestContent) || requestContent == null) {

            //定義Rquest物件,封裝訪問網路的請求資訊
//new Request.Builder()建立Request的內部類Builder的物件,預設通過get方法訪問網路
Request.Builder builder = new Request.Builder();
//關聯訪問網路的url,並將其轉換為Request物件
Request request = builder.url(url).build();
            return request;
} else {

            //初始化RequestBody,用於儲存我訪問網路的請求資訊
RequestBody requestBody = RequestBody.create(JSONTYPE, requestContent);
//初始化Request,用於封裝請求報頭
Request request = new Request.Builder().url(url).post(requestBody).build();
            return request;
}


    }


    //OkHttpClientget方法
public Object get(String url) throws IOException {


        Object result = null;
//關聯訪問網路的url,並將其轉換為Request物件
Request request = this.getRequest(url);
Response response = this.execute(request);
//檢測網路是否連線成功
if (response.isSuccessful()) {

            //獲取網連線資訊
String mess = response.message();
Log.d("tag", "mess = " + mess);
//初始化ResponseBody物件,用於封裝網路資源,該實體用許多訪問網路資源的方法
ResponseBody body = response.body();
//以字串的形式獲得網路
result = body.string();
//以字元流的形式獲得網路
//body.charStream();
            //以位元組的形式獲得網路
// body.bytes();
            //以位元組流的形式獲得網路
//body.byteStream();
} else {
            //如果沒有連線成功則丟擲io異常,答應出錯誤碼
throw new IOException("Unexcepted code = " + response.code());
}
        return result;
}


    //OkHttpClientget方法
public Object post(String url, String requestContent) throws IOException {

        String result = null;
//初始化Request,用於封裝請求報頭
Request request = this.getRequest(url, requestContent);
//訪問網路,返回相應報文
Response response = this.execute(request);
//檢測網路是否連線成功
if (response.isSuccessful()) {

            //獲取網連線資訊
String mess = response.message();
Log.d("tag", "mess = " + mess);
//初始化ResponseBody物件,用於封裝網路資源,該實體用許多訪問網路資源的方法
ResponseBody body = response.body();
//以字串的形式獲得網路
result = body.string();
//以字元流的形式獲得網路
//body.charStream();
            //以位元組的形式獲得網路
// body.bytes();
            //以位元組流的形式獲得網路
//body.byteStream();
} else {
            //如果沒有連線成功則丟擲io異常,答應出錯誤碼
throw new IOException("Unexcepted code = " + response.code());
}
        return result;
}


}

PS: 以上程式碼可以Copy在專案中直接執行

最後感謝大家的閱讀,由於本人是菜鳥,知識有限,有錯誤的地方歡迎大家提出。