1. 程式人生 > >Android網路請求框架Retrofit使用詳解

Android網路請求框架Retrofit使用詳解

前言

技術日新月異,一天不跑,就out了!
早點的Android的網路請求框架android-async-http,Volley,XUtils早已被拋諸腦後,到前段時間的OKHttp,再到最近一段時間大火的Retrofit,封裝的越來越好!程式碼越來越簡潔!
Retrofit與okhttp共同出自於大名鼎鼎的Square公司,retrofit就是對okhttp又做了一層封裝。把網路請求都交給給了Okhttp,下面就介紹一下Retrofit網路請求框架的使用!

使用

①現在Retrofit官方最新版本是2.1.0,那麼首先呢就是新增依賴了,在build.gradle中引入:

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-scalars:2.1.0' compile 'com.squareup.retrofit2:converter-gson:2.1.0'

注意:我們匯入的retrofit2各個包的版本號要一致,否則就會報錯!
第二個包是我們ConverterFactory的String依賴包,也就是說我們的返回值是String,第二個包是我們ConverterFactory的Gson依賴包,我們的反正值是我們定義的Gson實體類。具體怎麼使用,就要看我們在定義請求介面的時候,Call<T>泛型裡邊寫的是誰!!!
②然後需要我們定義一個請求介面:

import retrofit2.Call;
import retrofit2.http.POST;
import retrofit2.http.Query;

/**
 * Created by Admin on 2016/7/19.
 */
public interface RequestInterface {
    //%e5%8c%97%e4%ba%ac為北京的URL編碼,URLEncoder#encode("北京","UTF-8")
    //以此URL為例
    String URL = " http://api.36wu.com/Weather/GetWeather?district=%E5%8C%97%E4%BA%AC"
; @POST("Weather/GetWeather") Call<ResponseData> getData(@Query("district") String district); }

這裡的URL是我在網上隨便找的一個天氣API介面,請求方式是POST,當然我們也可以使用GET請求!

    @GET("{url}")
    Call<ResponseData> getData(@Path("url") String url);

Retrofit提供的請求方式註解有@GET和@POST,引數註解有@PATH和@Query等,@Query就是我們的請求的鍵值對的設定,我們構建Call物件的時候會傳入此引數,這裡的@Query("district")就是鍵,後邊的String district就是對應的值。@PATH指的是通過引數填充完整的路徑,這裡的引數url會被填充至{url}中,形成完整的Url請求地址,{url}相當於一個佔位符!
③接著給出我們的Gson實體類,因為這個API介面要申請appkey,我這裡直接拿來用的所以返回的json資訊是

 {
     "message":"該authkey錯誤或該authkey無權訪問此介面,如商用請購買服務,試用請線上申請。",
     "status":401
 }

所以我就以該json資料建立一個Gson實體類

public class ResponseData {
    private String message;
    private String status;

    @Override
    public String toString() {
        return "訊息|"+message+"\n"+
                "狀態碼|"+status;
    }
}

說到這,說一個題外話,這樣的json資料比較簡單,當我們遇到比較複雜的json資料的時候,我們也應該按照對應的返回欄位創建出對應的正確的Gson實體類。
可以參考一下下面這篇文章,寫的比較清晰:
http://blog.csdn.net/tkwxty/article/details/34474501
④最後就是具體的使用了:

Retrofit  retrofit=new Retrofit.Builder()
    .baseUrl("http://api.36wu.com/")
    //增加返回值為String的支援
    .addConverterFactory(ScalarsConverterFactory.create())
     //增加返回值為Gson的支援(返回實體類)
    .addConverterFactory(GsonConverterFactory.create())
    .build();

//這裡採用的是Java的動態代理模式,得到請求介面物件
RequestInterface 
requestInterface=retrofit.create(RequestInterface.class);
//傳入district的值,得到Call物件
Call<ResponseData> call=requestInterface.getData("%E5%8C%97%E4%BA%AC"); 
//call#enqueue請求網路
call.enqueue(new Callback<ResponseData>() {
            @Override
            public void onResponse(Call<ResponseData> call, Response<ResponseData> response) {
                Log.d("response",response.body().toString());
            }

            @Override
            public void onFailure(Call<ResponseData> call, Throwable t) {
                Log.d("failure","失敗"+t.toString());
            }
        });
    }

這裡有一個需要注意的問題:就是baseUrl和@POST的地址拼接問題,建議在baseUrl中最後加上/,而不要在POST中地址開始使用/,這樣才是拼接的正確的Url結果,否則會出現各種你意向不到的情況!
這樣整個網路請求就介紹完了,上面的列印結果:

訊息|該authkey錯誤或該authkey無權訪問此介面,如商用請購買服務,試用請線上申請。
狀態碼|401

如果我們在請求接口裡邊寫的是Call<String>,那麼得到的列印解果將是返回的整個json資料。

原始碼解析及用的設計模式

能力有限,分析的不透徹,我在簡書上面看到stay大神的分析,收藏一下:

推薦閱讀