HttpSender
HttpSender 是對OkHttp二次封裝,並與RxJava做到了無縫連線,支援任意Http請求方式,如:Get、Post、Head、Put等;也支援任意資料解析方法,如:Json、DOM解析等;並且可以很優雅的實現上傳/下載進度的監聽。
自問:目前已有Retrofit ,再結合RxJava,傳送請求已經很方便,為啥還要自己去封裝? 自答:Retrofit固然好用,但不是十分的好用,首先,有一定的學習成本;再一個,個人覺得Retrofit在便捷性、程式碼複用性上不是很友好,在看完本篇文章後,或許你會有同感。
本人是一個三流碼農,如有不足之處,理解萬歲!!!!!
HttpSender 開篇之功能使用篇,超好用、功能超級強大的Http請求框架
gradle依賴
implementation 'com.http.wrapper:httpsender:1.0.1'
複製程式碼
話不多說,開始,我們拿淘寶獲取IP的介面作為測試介面
返回的資料格式如下:
{
"code": 0,
"data": { //在這,為了簡單,在data下刪除了部分欄位,只保留3個欄位
"country": "美國",
"region": "華盛頓",
"city": "西雅圖"
}
}
複製程式碼
對應的Bean類
public class Response {
private int code;
private Address data;
//省略set、get方法
class Address {
private String country; //國家
private String region; //地區
private String city; //城市
//省略set、get方法
}
}
複製程式碼
傳送Get請求
String url = "http://ip.taobao.com/service/getIpInfo.php";
Param param = Param.get(url) //這裡get,代表Get請求
.add("ip", "63.223.108.42")//新增引數
.addHeader("accept", "*/*") //新增請求頭
.addHeader("connection", "Keep-Alive")
.addHeader("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
Disposable disposable = HttpSender
//SimpleParser是一個資料解析器,後續會有介紹,它需要傳入一個泛型,此泛型決定Http的返回型別
.from(param, new SimpleParser<Response>() {}) //from操作符,是非同步操作
.observeOn(AndroidSchedulers.mainThread()) //主執行緒回撥
.subscribe(new Consumer<Response>() {
@Override
public void accept(Response response) throws Exception {
//accept方法引數型別由上面SimpleParser傳入的泛型型別決定
//走到這裡說明Http請求成功,並且資料正確
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
//Http請求出現異常,有可能是網路異常,資料異常等
}
});
複製程式碼
傳送Post請求
String url = "http://ip.taobao.com/service/getIpInfo.php";
Param param = Param.postForm(url) //傳送Form表單形式的Post請求
.add("ip", "63.223.108.42")//新增引數
.addHeader("accept", "*/*") //新增請求頭
.addHeader("connection", "Keep-Alive")
.addHeader("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
Disposable disposable = HttpSender
//SimpleParser是一個資料解析器,後續會有介紹,它需要傳入一個泛型,此泛型決定Http的返回型別
.from(param, new SimpleParser<Response>() {}) //from操作符,是非同步操作
.observeOn(AndroidSchedulers.mainThread()) //主執行緒回撥
.subscribe(new Consumer<Response>() {
@Override
public void accept(Response response) throws Exception {
//accept方法引數型別由上面SimpleParser傳入的泛型型別決定
//走到這裡說明Http請求成功,並且資料正確
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
//Http請求出現異常,有可能是網路異常,資料異常等
}
});
複製程式碼
到這你會發現,Get跟Post請求僅僅是獲取Param物件的時候不一樣,即Param.get()和Param.postForm(),後續會對Param詳細介紹。
也許有人會說,傳送一個請求要寫那麼多的程式碼,太麻煩,不好用,我想說的是,以上案例是一個比較完整的請求流程,有帶引數、請求頭,又對返回資料做了自動解析,如果沒有這些,再結合Java 8 的Lambda表示式,你會發現,一切都是那麼的優雅 注:以下程式碼展示均結合Lambda表示式,不懂的同學去了解一下
String url = "http://www.baidu.com";
Disposable disposable = HttpSender
.fromGet(url) //fromGet非同步操作符,Get請求,內部呼叫了from(Param,Parser)方法
.observeOn(AndroidSchedulers.mainThread()) //主執行緒回撥
.subscribe(s -> {
//Http請求成功
}, throwable -> {
//Http請求出現異常
});
複製程式碼
怎麼樣,是不是很簡單,一條線下來,程式碼簡潔,邏輯清晰 接下來,我們試試檔案上傳,直接上程式碼
String url = "http://www.......";
Param param = Param.postForm(url) //傳送Form表單形式的Post請求
.add("file1", new File("xxx/1.png"))
.add("file2", new File("xxx/2.png"))
.add("key1", "value1")//新增引數,非必須
.add("key2", "value2")//新增引數,非必須
.addHeader("versionCode", "100"); //新增請求頭,非必須
Disposable disposable = HttpSender
.from(param, new SimpleParser<String>() {}) //from操作符,是非同步操作
.observeOn(AndroidSchedulers.mainThread()) //主執行緒回撥
.subscribe(s -> { //s為String型別,由SimpleParser類裡面的泛型決定的
//Http請求成功
}, throwable -> {
//Http請求出現異常
});
複製程式碼
看完你會發現,其實沒什麼,無非就拿到Param物件呼叫add方法傳入檔案,然後呼叫HttpSender傳送出去就ok了。
如果要監聽上傳進度呢?so easy!!!
String url = "http://www.......";
Param param = Param.postForm(url) //傳送Form表單形式的Post請求
.add("file1", new File("xxx/1.png"))
.add("file2", new File("xxx/2.png"))
.add("key1", "value1")//新增引數,非必須
.add("key2", "value2")//新增引數,非必須
.addHeader("versionCode", "100"); //新增請求頭,非必須
Disposable disposable = HttpSender
.upload(param, new SimpleParser<String>() {}) //注:如果需要監聽上傳進度,使用upload操作符
.observeOn(AndroidSchedulers.mainThread()) //主執行緒回撥
.doOnNext(progress -> {
//上傳進度回撥,0-100,僅在進度有更新時才會回撥
int currentProgress = progress.getProgress(); //當前進度 0-100
long currentSize = progress.getCurrentSize(); //當前已上傳的位元組大小
long totalSize = progress.getTotalSize(); //要上傳的總位元組大小
})
.filter(Progress::isCompleted)//過濾事件,上傳完成,才繼續往下走
.map(Progress::getResult) //到這,說明上傳完成,拿到Http返回結果並繼續往下走
.subscribe(s -> { //s為String型別,由SimpleParser類裡面的泛型決定的
//上傳成功,處理相關邏輯
}, throwable -> {
//上傳失敗,處理相關邏輯
});
複製程式碼
有上傳,那肯定就有下載,而且還是帶進度回撥的
String url = "http://update.9158.com/miaolive/Miaolive.apk";
//檔案儲存路徑
String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk";
Disposable disposable = HttpSender
.download(Param.get(url), destPath) //注意這裡使用download操作符
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(progress -> {
//下載進度回撥,0-100,僅在進度有更新時才會回撥
int currentProgress = progress.getProgress(); //當前進度 0-100
long currentSize = progress.getCurrentSize(); //當前已下載的位元組大小
long totalSize = progress.getTotalSize(); //要下載的總位元組大小
})
.filter(Progress::isCompleted)//下載完成,才繼續往下走
.map(Progress::getResult) //到這,說明下載完成,返回下載目標路徑
.subscribe(s -> {//s為String型別
//下載完成,處理相關邏輯
}, throwable -> {
//下載失敗,處理相關邏輯
});
複製程式碼
怎麼樣,是不是跟監聽上傳進度的程式碼差不多?這個就是與RxJava結合的好處。
如果我們不想監聽下載進度,更簡單,使用DownloadParser解析器
String url = "http://update.9158.com/miaolive/Miaolive.apk";
//檔案儲存路徑
String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk";
Disposable disposable = HttpSender
.from(Param.get(url), new DownloadParser(destPath)) //注意這裡使用DownloadParser解析器,並傳入本地路徑
.observeOn(AndroidSchedulers.mainThread())
.subscribe(s -> {
//下載成功,處理相關邏輯
}, throwable -> {
//下載失敗,處理相關邏輯
});
複製程式碼
小結: 怎麼樣?看完是不是覺得很簡單,傳送請求三部曲:
- 選擇合適的Http請求方式,呼叫Param的get、head、postForm、postJson、putForm等一系列靜態方法建立Param物件,隨後就可新增相關引數資訊,後續會詳細介紹Param
- 選擇合適的解析器Parser,目前已經實現了StringParser、SimpleParser、DownloadParser,後面會詳細介紹,可結合自身業務需求擴充套件Parser物件;
- 呼叫HttpSender類的fromGet、from、upload、download等操作符傳入Param和Parser物件即可,剩下的就交給RxJava處理了
注:fromGet和download操作符內部也使用了Param和Parser物件,只是做了一層封裝而已
到這你以為就結束了嗎?遠遠沒有,HttpSender更強大的是它的高擴充套件性,例如Param和Parser,後面會寫單獨的文章來介紹