RxHttp 一條鏈傳送請求之註解處理器 Generated API(四)

不怕天黑發表於2019-04-27

前言

在前面3篇文章中,我們對RxHttp做了整體的介紹,並帶領大家自定義Parser及Param,如果還沒閱讀,請檢視

如果還未閱讀前面文章,請檢視

RxHttp 一條鏈傳送請求,新一代Http請求神器(一)

RxHttp 一條鏈傳送請求之強大的資料解析功能(二)

RxHttp 一條鏈傳送請求之強大的Param類(三)

RxHttp庫已更新至1.0.4版本,詳情請檢視RxHttp 原始碼

這篇文章將介紹如何使用註解自定義API

Gradle 依賴

implementation 'com.rxjava.rxhttp:rxhttp:1.3.0'
//註解處理器,生成RxHttp類
annotationProcessor 'com.rxjava.rxhttp:rxhttp-compiler:1.3.0'
複製程式碼

簡介

在前面幾片文章,有讀者疑問,為啥要通過註解來生成RxHttp類,答案只有一個:為了使RxHttp更好用,通過@DefaultDomain註解,我們可以非常方便的設定baseUrl,這可能是目前對baseUrl最優雅的設定方案(歡迎打臉);通過@Domain ,我們可以非常方便的為單個請求指定非預設的baseUrl;通過@Param @Parser註解,我們就可以很方便的在RxHttp使用我們自定義的Param及Parser。 下面將一一介紹。

@DefaultDomain

現實開發中,大部人開發者都會將baseUrl 單獨抽取出來,RxHttp也考慮到了這一點,RxHttp通過@DefaultDomain註解來配置baseUrl,看程式碼

public class Url {
    @DefaultDomain() //設定為預設域名
    public static String baseUrl = "http://ip.taobao.com/";
}
複製程式碼

rebuild一下專案,此時我們傳送請求就可以直接傳入path路徑,如下:

  RxHttp.get("/service/getIpInfo.php")
        .add("key", "value")
        .asString()  
        .subscribe(s -> { //這裡的s為String型別,即Http請求的返回結果
           //成功回撥
        }, throwable -> {
           //失敗回撥
        });
複製程式碼

RxHttp在傳送請求前,會對url做判斷,如果沒有域名,就會自定加上預設的域名,也就是baseUrl。

@Domain

然後,如果我們不想使用預設的域名呢?RxHttp也考慮到來,提供了一個@Domain註解,我們再來看看用法:

public class Url {
    @Domain(name = "Update9158") //設定非預設域名,name 可不傳,不傳預設為變數的名稱
    public static String update = "http://update.9158.com";

    @DefaultDomain() //設定為預設域名
    public static String baseUrl = "http://ip.taobao.com/";
}
複製程式碼

此時再rebuild一下專案,就會在RxHttp類中生成一個setDomainToUpdate9158IfAbsent()方法,其中的Update9158字元就是name指定的名字,然後發請求就可以這樣:

  RxHttp.get("/service/getIpInfo.php")
        .setDomainToUpdate9158IfAbsent()
        .add("key", "value")
        .asString()  
        .subscribe(s -> { //這裡的s為String型別,即Http請求的返回結果
           //成功回撥
        }, throwable -> {
           //失敗回撥
        });
複製程式碼

此時,RxHttp檢測到url已經配置了域名,就不會再去使用預設的域名。同樣的,setDomainToUpdate9158IfAbsent也會檢測url 有沒有配置域名,如果配置了,也不會使用我們指定的域名。

注意:@Domain註解可以在多個地方使用,而@DefaultDomain()只能在一個地方使用,否則編譯不通過,很好理解,預設域名只可能有一個。兩個註解都要使用在public static修飾的String型別變數上,對final關鍵字沒有要求,可寫可不寫,這就表明,baseUrl 可以動態更改,RxHttp始終會拿到的最新的baseUrl 。怎麼樣,是不是很nice!!

@Parser

先來看看原始碼

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface Parser {
    //指定名字後,就會在RxHttp下生成fromXXX方法
    String name();
}
複製程式碼

@Parser標籤作用於Parser介面的實現類,指定名字後,Rebuild一下專案,就會在RxHttp下生成asXXX方法。

RxHttp 一條鏈傳送請求之強大的資料解析功能(二)一文中,我們也自定義了一個DataParser解析器,同時使用了@Parser(name = "Data")註解,我們再次貼上原始碼

@Parser(name = "Data")
public class DataParser<T> extends AbstractParser<T> {
     //省略內部程式碼
}
複製程式碼

然後Rebuild 一下專案,RxHttp下就會自動生產一個public <T> Observable<T> asData(Class<T> type)方法,如:

public class RxHttp {
  private Param param;

  private RxHttp(Param param) {
    this.param = param;
  }
  
  //通過註解Parser生成的方法
  public <T> Observable<T> asData(Class<T> type) {
    return from(DataParser.get(type));
  }
  //省略了其它方法
}
複製程式碼

此時我們就可以直接使用fromDataParser方法去解析資料了。

  String url = "http://ip.taobao.com/service/getIpInfo.php";
  RxHttp.postEncryptJson(url) //這裡get,代表Get請求
        .add("ip", "63.223.108.42")//新增引數
        .addHeader("accept", "*/*"); //新增請求頭
        .asData(Response.class)
        ...省略部分程式碼
複製程式碼

可見,程式碼更加的簡潔了

注:@Parser註解只能作用與Parser的實現類,不能是介面和抽象類,且必須要提供一個靜態的get方法,返回該實現類的一個例項物件,編譯時會檢查

@Param

先來看看@Param的原始碼

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface Param {
    //指定在RxHttp類中生成的靜態方法名
    String methodName();
}
複製程式碼

@Param標籤只能作用於AbstractPostParam的實現類上,否則編譯器會報錯,指定方法名後,Rebuild一下專案,就會自動在RxHttp類下生成指定方法名的靜態方法。

RxHttp 一條鏈傳送請求之強大的Param類(三)一文中,我們自定義了一個PostEncryptJsonParam,併為它使用了註解標籤@Param(methodName = "postEncryptJson")我們再次貼上該類的原始碼

@Param(methodName = "postEncryptJson") //指定postEncryptJson為方法名
public class PostEncryptJsonParam extends AbstractPostParam {
     //省略內部程式碼
}
複製程式碼

然後Rebuild 一下專案,就可以看到在RxHttp下多了一個postEncryptJson方法,並在方法內new 出了一個PostEncryptJsonParam物件傳給了RxHttp

public class RxHttp {
  private Param param;

  private RxHttp(Param param) {
    this.param = param;
  }
  
  public static RxHttp with(Param param) {
    return new RxHttp(param);
  }
  
  //通過註解Param生成的方法
  public static RxHttp postEncryptJson(String url) {
    return with(new PostEncryptJsonParam(url));
  }
  //省略了其它方法
}
複製程式碼

接下來,我們就可以直接通過RxHttp傳送PostEncryptJsonParam請求

  String url = "http://ip.taobao.com/service/getIpInfo.php";
  RxHttp.postEncryptJson(url) //這裡get,代表Get請求
        .add("ip", "63.223.108.42")//新增引數
        .addHeader("accept", "*/*") //新增請求頭
        //省略部分程式碼
複製程式碼

可見@Param標籤,在一定程度上降低了耦合,使我們並不需要關注具體的實現,使用 RxHttp類即可搞定任意請求

注:@Param標籤只能作用與Param介面的實現類,該類不能是介面、抽象類,且必須提供一個public 且僅帶一個url引數的構造方法,在編譯時會做檢查。

小結

最後,本文如果有寫的不對的地方,請廣大讀者指出。 如果覺得我寫的不錯,記得給我點贊RxHttp

轉載請註明出處,謝謝?。

相關文章