1. 程式人生 > >安卓開發學習之Retrofit2.0的使用

安卓開發學習之Retrofit2.0的使用

介紹

Retrofit2.0是一個比較流行的網路開源庫,可以用來進行同步或非同步的網路請求,現在,我就通過例子(訪問翻譯詞霸進行翻譯)講解的方式,給大家演示一下其基本用法

使用步驟

新增依賴

compile 'com.squareup.retrofit2:retrofit:2.0.2'
// Retrofit庫
compile 'com.squareup.retrofit2:converter-gson:2.0.2'

一個是Retrofit庫,一個是gson庫

定義結果類

翻譯詞霸的結果格式是這樣:

    status:翻譯狀態

    Content欄位:翻譯結果的封裝:裡面有from(原文語言)、to(翻譯成哪種語言)、vendor(翻譯提供者,就到底誰翻譯的,有道還是誰)、out(翻譯結果)、errNo(錯誤碼,沒錯誤則為0)

故而把結果類定義成下面的樣子,裡面封裝一個內部類Content:

public class Result {
    private int status;

    private Content content;

    private class Content{
        private String from;
        private String to;
        private String vendor;
        private String out;
        private int errNo;

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder("{");
            sb.append("\"from\":\"")
                    .append(from).append('\"');
            sb.append(",\"to\":\"")
                    .append(to).append('\"');
            sb.append(",\"vendor\":\"")
                    .append(vendor).append('\"');
            sb.append(",\"out\":\"")
                    .append(out).append('\"');
            sb.append(",\"errNo\":")
                    .append(errNo);
            sb.append('}');
            return sb.toString();
        }
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("{");
        sb.append("\"status\":")
                .append(status);
        sb.append(",\"content\":")
                .append(content.toString());
        sb.append('}');
        return sb.toString();
    }
}

定義請求介面

Retrofit裡網路請求的執行,要先通過呼叫自定義接口裡的方法獲取一個Call物件,而後Call物件同步或非同步執行請求。

所以我們要自定義請求介面,但要用上retrofit的註解

public interface IRequest {
    @GET("ajax.php")
    Call<Result> getResult(@Query("a") String a,@Query("f") String from
            ,@Query("t") String to,@Query("w") String w);
    //@Query用於在?之後傳參
}

解釋:@GET表示用get方法進行網路請求,裡面的引數是相對地址,也可以用絕對地址,但不推薦那樣,程式碼複用性不好

         Call<Result>網路請求完後,返回一個Call物件,這個是Retrofit中封裝好的類,泛型特定化為自定義的Result

        方法引數列表,網路請求的引數,順序不可打亂。以@Query("a") String a為例,意思是加上一個引數a,值是外界傳來的String型別的a

        上面方法執行後,生成的url是:

                ajax.php?a=a&f=from&t=to&w=w

呼叫API進行網路請求

構造Retrofit物件

我們要用到Retrofit物件來開啟網路請求,於是就要呼叫一系列的API

Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();

解釋:baseUrl()設定請求的基礎URL,引數是我寫的靜態final欄位BASE_URL

public static final String BASE_URL = "http://fy.iciba.com/";

        ConverterFactory:解析工廠,一般就直接用GSON,把返回的json資料解析成java物件

        CallAdapterFactory:直接用RxJava的工廠

構造請求介面物件
final IRequest request = retrofit.create(IRequest.class);

看原始碼的話,這兒是一個動態代理

呼叫介面方法,獲取請求物件
Call<Result> call = request.getResult("fy", "auto", "auto", "I`m%20good%20to%go!");

按順序傳入引數,這樣的話,請求URL就是:

    http://fy.iciba.com/ajax.php?a=fy&f=auto&t=auto&w=I`m%20good%20to%20go!

    解釋:a=fy,固定的

            f=auto:自動識別原文語言

            t=auto:預設譯文語言是中文

            w=I`m%20good%2to%20go!:原文是I`m%20good%2to%20go!,網路請求中空格用%20代替

請求物件執行請求
call.enqueue(new Callback<Result>() {
            //enqueue():非同步
            ...
        });

enqueue()方法執行非同步請求,execute()則為同步

裡面傳入回撥介面,處理請求後的回撥

處理回撥
 @Override
 public void onResponse(Call<Result> call, Response<Result> response) {
     int code = response.code();
     if (code == 200) {
         String result = response.body().toString();
         Log.i(TAG, result);
     } else {
         Log.i(TAG, "responseCode=" + code);
     }
 }

 @Override
 public void onFailure(Call<Result> call, Throwable t) {
     t.printStackTrace();
     dismissDialog();
 }

onResponse()是正常請求的結果回撥,onFailure()是發生異常的回撥

我們只看onResponse():

請求碼成功的情況下,獲取response.body()、也就是result物件

執行結果


可以看到,返回了正確結果。