- 本文簡(jiǎn)單的講下如何將Volley的回調(diào)模式跟RxAndroid結(jié)合起來(lái)使用。使用RxAndroid的主要原因就是其能實(shí)現(xiàn)鏈?zhǔn)骄幋a,代碼比較好看莹桅;使用Volley的主要原因是大廠出品質(zhì)量有保障,項(xiàng)目涉及的網(wǎng)絡(luò)請(qǐng)求也比較簡(jiǎn)單。
結(jié)合使用步驟:
1.引入需要用到的資源:
compile 'com.android.volley:volley:1.0.0'
compile 'io.reactivex:rxandroid:1.2.1'
2.首先自定義自己的請(qǐng)求類
自定義請(qǐng)求類HttpJsonRequest
珊擂,該類繼承于com.android.volley.Request
,volley
有幾個(gè)自己定義好的請(qǐng)求類费变,在com.android.volley.toolbox
下摧扇,根據(jù)需要使用。我這里為了跟RxAndrod結(jié)合挚歧,也為了傳遞傳統(tǒng)的鍵值對(duì)形式參數(shù)扛稽,采用自定義的。
HttpJsonRequest.java
如下:
import java.util.List;
import org.json.JSONObject;
import android.text.TextUtils;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HttpHeaderParser;
import rx.Observer;
public class HttpJsonRequest extends Request<JSONObject> {
private final String PROTOCOL_CHARSET = "utf-8";
/**
* 鍵值對(duì)形式參數(shù)
*/
private List<ParamItem> mParams;
/**
* 觀察者滑负,在請(qǐng)求結(jié)束后在张,向其傳遞成功、失敗的事件
*/
private Observer<? super JSONObject> mObserver;
public HttpJsonRequest(int method, String url, List<ParamItem> params, Observer<? super JSONObject> observer) {
super(method, url, null);
mObserver = observer;
mParams = params;
// 設(shè)置請(qǐng)求超時(shí)時(shí)間以及重試次數(shù)
setRetryPolicy(new DefaultRetryPolicy(60000, 0, 1.0f));
}
/**
* 該方法必須重寫0健G撇簟!
* 請(qǐng)求完成時(shí)觸發(fā)觀察者中事件凡傅,記得加onCompleted();
*/
@Override
protected void deliverResponse(JSONObject response) {
mObserver.onNext(response);
mObserver.onCompleted();
}
/**
* 該方法必須重寫1俦贰!夏跷!
* 發(fā)生錯(cuò)誤時(shí)哼转,觸發(fā)事件
*/
@Override
public void deliverError(VolleyError error) {
mObserver.onError(error);
}
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
if (TextUtils.isEmpty(jsonString)) {
return Response.success(new JSONObject(), HttpHeaderParser.parseCacheHeaders(response));
} else {
return Response.success(new JSONObject(jsonString), HttpHeaderParser.parseCacheHeaders(response));
}
} catch (Exception e) {
return Response.error(new ParseError(e));
}
}
/**
* 由于參數(shù)是按照傳統(tǒng)的鍵值對(duì)形式傳遞至后臺(tái),所以這塊需要重寫;
* 如果能保證參數(shù)名稱不重復(fù)槽华,其實(shí)只要重寫Request中g(shù)etParams()方法即可壹蔓,我這里直接重寫的getBody(),因?yàn)樘峤粓D片時(shí)是同一個(gè)參數(shù)名稱多次提交
* Volley.toolbox中提供了幾種強(qiáng)格式的request,比如com.android.volley.toolbox.JsonObjectRequest,要求參數(shù)是json格式;
* 實(shí)際開發(fā)中猫态,前后臺(tái)交互模式很多佣蓉,主要就是修改getBody()來(lái)達(dá)到自定義目的披摄。
*/
@Override
public byte[] getBody() {
String paramStr;
if (mParams == null) {
paramStr = "";
} else {
StringBuilder params = new StringBuilder();
for (ParamItem p : mParams) {
params.append("&").append(p.getKey()).append("=").append(p.getValue());
}
paramStr = params.toString();
if (paramStr.length() > 0) {
// 去除第一個(gè)&
paramStr = paramStr.substring(1);
}
}
try {
return paramStr.getBytes(PROTOCOL_CHARSET);
} catch (Exception uee) {
throw new RuntimeException("Encoding not supported: " + PROTOCOL_CHARSET, uee);
}
}
}
這里需要注意的點(diǎn),參見(jiàn)代碼里的注釋勇凭。其核心就是deliverResponse
和deliverError
兩個(gè)方法的重寫疚膊,其原來(lái)的方式,可以看volley.toolbox
下的幾個(gè)請(qǐng)求類源碼
3.初始化請(qǐng)求隊(duì)列以及加入請(qǐng)求虾标、取消請(qǐng)求方法
private RequestQueue mRequestQueue;
/**
* 獲取請(qǐng)求隊(duì)列
*/
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(this);
}
return mRequestQueue;
}
/**
* 將一個(gè)請(qǐng)求加入隊(duì)列寓盗,,并設(shè)置其TAG;
* 其中tag通常就是當(dāng)前請(qǐng)求所處的頁(yè)面璧函,頁(yè)面銷毀時(shí)調(diào)用cancelALl終止被頁(yè)面請(qǐng)求
*/
public <T> void addToRequestQueue(Request<T> req, Object tag) {
addToRequestQueue(req, tag.getClass().getSimpleName());
}
private <T> void addToRequestQueue(Request<T> req, String tag) {
req.setTag(tag);
BuglyLog.d(TAG, "添加請(qǐng)求至隊(duì)列:" + req.getUrl());
getRequestQueue().add(req);
}
/**
* 取消指定TAG的請(qǐng)求傀蚌,通常在onDestory()中調(diào)用
*/
public void cancelPendingRequests(Object tag) {
cancelPendingRequests(tag.getClass().getSimpleName());
}
private void cancelPendingRequests(String tag) {
BuglyLog.e(TAG, "從隊(duì)列里去除指定TAG的請(qǐng)求:" + tag);
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
這塊沒(méi)什么好說(shuō)的,如果你要集成okhttp,就是在 Volley.newRequestQueue(this)
這里做文章
4.RxAndroid與Volley結(jié)合使用
主要代碼如下:
/**
* 執(zhí)行注冊(cè)
*/
private void doRegister(String email, String password) {
int versionCode = com.afap.utils.Utils.getAppVersionCode(getContext());
String sdk = Build.VERSION.RELEASE;
Observable.create(new Observable.OnSubscribe<JSONObject>() {
@Override
public void call(final Subscriber<? super JSONObject> subscriber) {
String url = "http://www.weather.com.cn/data/cityinfo/101010100.html";
List<ParamItem> params = new ArrayList<>();
HttpJsonRequest request = new HttpJsonRequest(Request.Method.GET, url, null, subscriber);
MyApplication.getInstance().addToRequestQueue(request, RegisterFormFragment.this);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<JSONObject>() {
@Override
public void onCompleted() {
BuglyLog.i(TAG, "Observer.onCompleted");
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
BuglyLog.e(TAG, "Observer.onError");
}
@Override
public void onNext(JSONObject json) {
BuglyLog.i(TAG, "Observer.onNext");
BuglyLog.i(TAG, json.toString());
}
});
}
@Override
public void onDestroy() {
MyApplication.getInstance().cancelPendingRequests(this);
super.onDestroy();
}
以上蘸吓,就已經(jīng)將Volley和RxAndroid串起來(lái)了善炫。最最關(guān)鍵的一步就是deliverResponse
和deliverError
.