国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Retrofit:聲明 ApiService接口

chengjianhua / 2063人閱讀

摘要:因為使用默認將返回的對象對象轉換成了的對象了使用但是我們在使用后,有時可能會這樣聲明接口這樣定義可以很方便的在返回中直接一個對象了登錄成功登錄失敗但是這樣有一個問題就是會丟失的元數據,因為對象我們是沒法訪問的。

Retrofit:聲明 ApiService接口

我們在使用Retrofit的時候只需要把URL通過注解的形式寫到APIService文件中就行了。

比如登錄功能:

如果后臺的成功返回格式為

{    
    code:0;
    Message:"login success"
}

失敗的返回格式為

{    
    code:-1;
    Message:"login failed"
}

我們定義個一個Bean類LoginResult.

public class LoginResult{
    private int code;
    private String message;
    
    //get/set
}

不使用Rxjava

在方法的定義中,如果不適用Rxjava的話,

@Post
@FormUrlEncoded
Call login(@Field("userName") String userName, @Field("password")String password);

在使用的時候們只需要使用apiService.login("dsf", "dsf"),就好了。該方法會返回一個Call 對象

我們只需要或者異步執行

//同步執行
Response response = call.execute();
//異步調用
call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

            }
        });

然后我們在返回結果里面操作就行了,如果我們需要Response里面的元數據,比如header里面的信息的話,直接從Response取就好了。

因為Retrofit 使用DefaultCallAdapterFactory默認將OKHttp返回的Call對象(OkHttp對象)轉換成了Retrofit的Call對象了

使用Rxajva Observable

但是我們在使用RxJava后,有時可能會這樣聲明接口

@Post
@FormUrlEncoded
Observable login(@Field("userName") String userName, @Field("password")String password);

這樣定義可以很方便的在返回中直接subScribe一個Action對象了

Observable observable = model.login("dfs", "dfs");
observable.subscribe(new Action1() {
            @Override
            public void call(LoginResult loginResult) {
                if (loginResult.getCode() == 0) {
                    //登錄成功   
                } else {
                    //登錄失敗
                }
                    
            }
        });

但是這樣有一個問題就是會丟失Response的元數據,因為Response對象我們是沒法訪問的。因為Retrofit已經幫助我們做了轉換,直接把我們接口方法里定義的數據類型轉換好后返回給我們了。去掉了Response信息。

Observable>

我們可以這么定義接口

@Post
@FormUrlEncoded
Observable> login(@Field("userName") String userName, @Field("password")String password);

這樣我們就得到這樣的返回結果。

Observable> observable = model.login("dfs", "dfs");
observable.subscribe(new Action1>() {
            @Override
            public void call(Response loginResultResponse) {
                if (loginResultResponse.code() == 200){
                    LoginResult body = loginResultResponse.body();
                }else {
                    //登錄失敗
                }
            }
        });

這樣就能拿到Response信息了,然后根據Response code判斷是否登錄成功了。

但是這樣有個問題是我們寫接口會特備繁瑣,每次都得使用Response<>泛型。一般我們都寫作Observable login();

其實我們一般情況下也不關注Response信息的。但是不排除特殊情況

比如這種情況

https://academy.realm.io/cn/p...

這篇文章提到的分頁加載的情況,其實這種情況也可以將下一個頁面的URL放到Response body里返回。

這里只是給出了一種情景。

現實中解決方案很多種,只能折中了,其實我們沒必要使用Response的Response code 來判斷接口是否調用成功了。因為Retrofit都幫我們做過了。所以我們定義接口的時候只要使用Observable就好了。

我們在使用Retrofit + Rxjava 的時候一般都這么生成Retrofit client的

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

這里RxJavaCallAdapterFactory生成的CallAdapter對象就幫我們做好了結果的轉換

我們看一下RxJavaCallAdapterFactory的聲明。

/**
 * A {@linkplain CallAdapter.Factory call adapter} which uses RxJava for creating observables.
 * 

* Adding this class to {@link Retrofit} allows you to return {@link Observable} from service * methods. *


 * interface MyService {
 *   @GET("user/me")
 *   Observable getUser()
 * }
 * 
* There are three configurations supported for the {@code Observable} type parameter: 有三種配置支持Observable的類型參數 *
    *
  • Direct body (e.g., {@code Observable}) calls {@code onNext} with the deserialized body * for 2XX responses and calls {@code onError} with {@link HttpException} for non-2XX responses and * {@link IOException} for network errors.
  • 第一種:直接使用Observable聲明接口, 將會針對所有的2** Response code會調用onNext(T t)方法。所有的Response code 不是200的都調用OnError(Throwable t)方法拋出一個HttpException 異常,網絡錯誤調用onError()方法,并拋出一個IO異常。 *
  • Response wrapped body (e.g., {@code Observable>}) calls {@code onNext} * with a {@link Response} object for all HTTP responses and calls {@code onError} with * {@link IOException} for network errors
  • 第二種:如果使用Observable>聲明接口,那么針對所有的Response將會調用onNext(Respones response)方法,針對網絡異常將調用OnError()方法,并拋出一個IO異常。 *
  • Result wrapped body (e.g., {@code Observable>}) calls {@code onNext} with a * {@link Result} object for all HTTP responses and errors.
  • 第三種:如果使用Observable聲明接口。所有的Response和Error將會調用onNext方法。 注意:這個Result是Retrofit提供的。 *
*/
結論

結論就是,如果我們沒有對Response有特殊的需求的話,直接在接口聲明處直接聲明成Observable是最方便最直觀的。

這篇文章本應該和Retofit源碼分析一起寫的,奈何Retrofit的源碼實在是太晦澀難懂了

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/75933.html

相關文章

  • Retrofit源碼分析

    摘要:看下圖所示,摘自網絡的創建流程源碼分析實例是使用建造者模式通過類進行創建的。創建了一個含有對象實例的,并返回給源碼分析添加一個調用適配器工廠,用于支持服務方法返回類型注意生產的是,那么又是什么呢可以看到源代碼如下所示,它是一個接口。 目錄介紹 1.首先回顧Retrofit簡單使用方法 2.Retrofit的創建流程源碼分析 2.1 Retrofit對象調用Builder()源碼解...

    zero 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<