RxVolley 項目地址: https://github.com/kymjs/RxVolley QQ問答群:1群 257053751(付費); 2群 201055521(付費); 3群 110775129(付費) 付費群,請帶著問題來,閑聊者不建議隨意加入,雖說不會踢人
概述
RxVolley 是一個基于Volley 的網(wǎng)絡(luò)請求庫; 同時支持RxJava ; 可以選擇使用OKHttp 替代默認的 HttpUrlConnection 做網(wǎng)絡(luò)請求; 可以選擇使用圖片加載功能(復(fù)用的網(wǎng)絡(luò)請求將有效減少apk體積); 移除了原Volley 的 HttpClient 相關(guān) API ,可在 API23 環(huán)境編譯; 內(nèi)置了RxBus 的實現(xiàn),可有效替換掉EventBus 等相關(guān)庫;
即將支持 RxJava2.0
依賴
使用RxVolley,需要在你的build.gradle 文件中加入
compile 'com.kymjs.rxvolley:rxvolley:1.1.4'
如果你還想使用OKhttp來替代默認的HttpUrlconnection ,需要加入
compile 'com.kymjs.rxvolley:okhttp:1.1.4'
//或者okhttp3(二選一)
compile 'com.kymjs.rxvolley:okhttp3:1.1.4'
如果你想使用RxVolley的圖片加載功能(復(fù)用http模塊可以有效減少apk大小),需要加入
compile 'com.kymjs.rxvolley:bitmapcore:1.1.4'
使用 RxVolley 做網(wǎng)絡(luò)請求
簡潔實現(xiàn)
//get請求簡潔版實現(xiàn)
RxVolley.get("http://www./feed.xml", new HttpCallback() {
@Override
public void onSuccess(String t) {
Loger.debug("請求到的數(shù)據(jù):" + t);
}
});
//post請求簡潔版實現(xiàn)
HttpParams params = new HttpParams();
params.put("name", "kymjs");
params.put("age", 18);
params.put("image", new File("path"))//文件上傳
RxVolley.post("http:///feed.xml", params, new HttpCallback() {
@Override
public void onSuccess(String t) {
Loger.debug("請求到的數(shù)據(jù):" + t);
}
});
對Cookie等請求頭的處理
//用戶登錄邏輯(HttpCallback中有很多重載方法,可以選擇需要的實現(xiàn))
HttpParams params = new HttpParams();
params.put("name", "kymjs");
params.put("age", 18);
params.put("password", "helloword");
RxVolley.post("http:///login", params, new HttpCallback() {
@Override
public void onSuccess(Map<String, String> headers, byte[] t) {
Loger.debug("請求到的數(shù)據(jù):" + new String(t));
// 獲取到的cookie
Loger.debug("===" + headers.get("Set-Cookie"));
}
});
//向服務(wù)器傳遞cookie信息
HttpParams params = new HttpParams();
params.put("name", "kymjs");
params.put("age", 100);
params.putHeaders("cookie", "your cookie");
RxVolley.post("http:///update", params, new HttpCallback() {
@Override
public void onSuccess(String t) {
Loger.debug("請求到的數(shù)據(jù):" + t);
}
});
比起 入門 章節(jié)講述的網(wǎng)絡(luò)請求,你可能希望有更多的需求
構(gòu)建網(wǎng)絡(luò)請求
HttpParams params = new HttpParams();
//同之前的設(shè)計,傳遞 http 請求頭可以使用 putHeaders()
params.putHeaders("cookie", "your cookie");
params.putHeaders("User-Agent", "rxvolley");
//傳遞 http 請求參數(shù)可以使用 put()
params.put("name", "kymjs");
params.put("age", "18");
//http請求的回調(diào),內(nèi)置了很多方法,詳細請查看源碼
//包括在異步響應(yīng)的onSuccessInAsync():注不能做UI操作
//網(wǎng)絡(luò)請求成功時的回調(diào)onSuccess()
//網(wǎng)絡(luò)請求失敗時的回調(diào)onFailure():例如無網(wǎng)絡(luò),服務(wù)器異常等
HttpCallback callback = new HttpCallback(){
@Override
public void onSuccessInAsync(byte[] t) {
}
@Override
public void onSuccess(String t) {
}
@Override
public void onFailure(int errorNo, String strMsg) {
}
}
ProgressListener listener = new ProgressListener(){
/**
* @param transferredBytes 進度
* @param totalSize 總量
*/
@Override
public void onProgress(long transferredBytes, long totalSize){
}
}
new RxVolley.Builder()
.url("http://www./rss.xml") //接口地址
//請求類型,如果不加,默認為 GET 可選項:
//POST/PUT/DELETE/HEAD/OPTIONS/TRACE/PATCH
.httpMethod(RxVolley.Method.GET)
//設(shè)置緩存時間: 默認是 get 請求 5 分鐘, post 請求不緩存
.cacheTime(6)
//內(nèi)容參數(shù)傳遞形式,如果不加,默認為 FORM 表單提交,可選項 JSON 內(nèi)容
.contentType(RxVolley.ContentType.FORM)
.params(params) //上文創(chuàng)建的HttpParams請求參數(shù)集
//是否緩存,默認是 get 請求 5 緩存分鐘, post 請求不緩存
.shouldCache(true)
.progressListener(listener) //上傳進度
.callback(callback) //響應(yīng)回調(diào)
.encoding("UTF-8") //編碼格式,默認為utf-8
.doTask(); //執(zhí)行請求操作
對 RxJava 的支持
RxVolley 支持返回一個 Observable<Result> 類型的數(shù)據(jù),如下是 Result 類的原型
public class Result {
public String url;
public byte[] data;
public VolleyError error;
public Map<String, String> headers;
public int errorCode;
}
執(zhí)行一次請求,并返回 Observable<Result>
Observable<Result> observable = new RxVolley.Builder()
.url("http://www./rss.xml")
//default GET or POST/PUT/DELETE/HEAD/OPTIONS/TRACE/PATCH
.httpMethod(RxVolley.Method.POST)
.cacheTime(6) //default: get 5min, post 0min
.params(params)
.contentType(RxVolley.ContentType.JSON)
.getResult(); // 使用getResult()來返回RxJava數(shù)據(jù)類型
//當(dāng)拿到 observable 對象后,你可以設(shè)置你自己的 subscriber
observable.subscribe(subscriber);
完整的使用示例
public class MainActivity extends AppCompatActivity {
private Subscription subscription;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Observable<Result> observable = new RxVolley.Builder()
.url("http:///feed.xml")
.contentType(RxVolley.ContentType.FORM)
.getResult();
subscription = observable
.map(new Func1<Result, String>() {
@Override
public String call(Result result) {
return new String(result.data);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
Log.i("kymjs", "======網(wǎng)絡(luò)請求結(jié)束");
}
@Override
public void onError(Throwable e) {
Log.i("kymjs", "======網(wǎng)絡(luò)請求失敗" + e.getMessage());
}
@Override
public void onNext(String s) {
Log.i("kymjs", "======網(wǎng)絡(luò)請求" + s);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (subscription != null && subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
}
}
自定義請求
也許你是 Volley 的重度使用者(就像我),那么你一定是因為 Volley 自由的擴展性而愛上它的。 你可以通過創(chuàng)建一個Request<?> 的子類,自由配置請求策略,緩存策略,數(shù)據(jù)傳輸加密,重試策略等。 最后通過
RxVolley.Builder().setRequest(yourRequest).doTask();
去執(zhí)行你的自定義 Request
一個典型自定義Request的示例:
/**
* Form表單形式的Http請求
*/
public class FormRequest extends Request<byte[]> {
private final HttpParams mParams;
public FormRequest(RequestConfig config, HttpParams params, HttpCallback callback) {
super(config, callback);
if (params == null) {
params = new HttpParams();
}
this.mParams = params;
}
@Override
public String getCacheKey() {
if (getMethod() == RxVolley.Method.POST) {
return getUrl() + mParams.getUrlParams();
} else {
return getUrl();
}
}
@Override
public String getBodyContentType() {
if (mParams.getContentType() != null) {
return mParams.getContentType();
} else {
return super.getBodyContentType();
}
}
@Override
public ArrayList<HttpParamsEntry> getHeaders() {
return mParams.getHeaders();
}
@Override
public byte[] getBody() {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
mParams.writeTo(bos);
} catch (IOException e) {
Loger.debug("FormRequest#getBody()--->IOException writing to ByteArrayOutputStream");
}
return bos.toByteArray();
}
@Override
public Response<byte[]> parseNetworkResponse(NetworkResponse response) {
return Response.success(response.data, response.headers,
HttpHeaderParser.parseCacheHeaders(getUseServerControl(), getCacheTime(),
response));
}
@Override
protected void deliverResponse(ArrayList<HttpParamsEntry> headers, final byte[] response) {
if (mCallback != null) {
HashMap<String, String> map = new HashMap<>(headers.size());
for (HttpParamsEntry entry : headers) {
map.put(entry.k, entry.v);
}
mCallback.onSuccess(map, response);
}
}
@Override
public Priority getPriority() {
return Priority.IMMEDIATE;
}
}
文件(圖片)下載
利用 RxVolley 的自定義請求,在庫中內(nèi)置了文件下載功能。你可以使用
//下載進度(可選參數(shù),不需要可不傳)
listener = new ProgressListener() {
@Override
public void onProgress(long transferredBytes, long totalSize) {
Loger.debug(transferredBytes + "======" + totalSize);
}
}
//下載回調(diào),內(nèi)置了很多方法,詳細請查看源碼
//包括在異步響應(yīng)的onSuccessInAsync():注不能做UI操作
//下載成功時的回調(diào)onSuccess()
//下載失敗時的回調(diào)onFailure():例如無網(wǎng)絡(luò),服務(wù)器異常等
HttpCallback callback = new HttpCallback(){
@Override
public void onSuccessInAsync(byte[] t) {
}
@Override
public void onSuccess(String t) {
}
@Override
public void onFailure(int errorNo, String strMsg) {
}
}
RxVolley.download(FileUtils.getSDCardPath() + "/a.apk",
"https://www.oschina.net/uploads/osc-android-app-2.4.apk",
listener, callback);
download()原型
既然說了下載功能 是利用 RxVolley 的自定義請求創(chuàng)建的,不妨看看他的方法實現(xiàn):
/**
* 下載
*
* @param storeFilePath 本地存儲絕對路徑
* @param url 要下載的文件的url
* @param progressListener 下載進度回調(diào)
* @param callback 回調(diào)
*/
public static void download(String storeFilePath, String url, ProgressListener
progressListener, HttpCallback callback) {
RequestConfig config = new RequestConfig();
config.mUrl = url;
FileRequest request = new FileRequest(storeFilePath, config, callback);
request.setOnProgressListener(progressListener);
new Builder().setRequest(request).doTask();
}
更多可選設(shè)置
理論上來說,一切的請求設(shè)置都可以通過自定義 Request 來完成。 但是,如果你和我一樣是個懶人,當(dāng)然更希望這些早就有人已經(jīng)做好了。
設(shè)置文件緩存的路徑
默認的文件緩存路徑是在SD卡根目錄的 /RxVolley 文件夾下,你可以通過如下語句設(shè)置你的 cacheFolder
RxVolley.setRequestQueue(RequestQueue.newRequestQueue(cacheFolder));
需要注意的是,setRequestQueue 方法必須在 BitmapCore.Build() 和 RxVolley.Build() 方法執(zhí)行之前調(diào)用,也就是在使用 RxVolley 以前先設(shè)置配置信息。建議在 Application 類中完成這些設(shè)置。
Https設(shè)置
如果不設(shè)置,默認信任全部的https證書??梢詡魅胱远x SSLSocketFactory
RxVolley.setRequestQueue(RequestQueue.newRequestQueue(cacheFolder), new HttpConnectStack(null, sslSocketFactory));
需要注意的是,setRequestQueue 方法必須在 RxVolley.Build() 方法執(zhí)行之前調(diào)用,也就是在使用 RxVolley 以前先設(shè)置配置信息。建議在 Application 類中完成這些設(shè)置。
一個自定義設(shè)置SSLSocketFactory的相關(guān)示例:
//下載的證書放到項目中的assets目錄中
InputStream ins = context.getAssets().open("app_pay.cer");
CertificateFactory cerFactory = CertificateFactory
.getInstance("X.509");
Certificate cer = cerFactory.generateCertificate(ins);
KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC");
keyStore.load(null, null);
keyStore.setCertificateEntry("trust", cer);
SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore);
RxVolley.setRequestQueue(RequestQueue.newRequestQueue(RxVolley.CACHE_FOLDER), new HttpConnectStack(null, sslSocketFactory));
Build()中的可選設(shè)置
- 詳細請參閱 RxVolley$Builder 類中代碼。
//請求超時時間
timeout()
//為了更真實的模擬網(wǎng)絡(luò),如果讀取緩存,延遲一段時間再返回緩存內(nèi)容
delayTime()
//緩存有效時間,單位分鐘
cacheTime()
//使用服務(wù)器控制的緩存有效期,即cookie有效期
//(如果使用服務(wù)器端控制,則無視#cacheTime())
useServerControl()
//啟用緩存
shouldCache()
//重連策略,Volley默認的重連策略是timeout=3000,重試1次
retryPolicy()
|