???? (一) Volley的二次封装
protected <T> void doSimpleRequest(String url, HashMap<String, String> params, final Class<?> clazz, final SimpleCallback callback) {
String requestUrl = urlBuilder(url, params);
Logger.e("url", requestUrl);
Response.Listener<String> successListener = new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
T bean = GsonUtils.getFromStr(clazz, response);
callback.onResponse(bean);
} catch (Exception e) {
callback.onError();
}
}
};
Response.ErrorListener errorListener = new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
callback.onError();
}
};
StringRequest requestRequest = new StringRequest(url, params, successListener, errorListener);
LeSportsApplication.getApplication().addHttpRequest(requestRequest);
}
?
package com.lesports.common.volley.toolbox;
import android.os.Looper;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.lesports.common.volley.NetworkResponse;
import com.lesports.common.volley.ParseError;
import com.lesports.common.volley.Request;
import com.lesports.common.volley.Response;
import com.letv.core.log.Logger;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
/**
* Created by liuyu8 on 2015/9/15.
*/
public class MyGsonRequest<T> extends Request<T>{
private final Logger mLogger = new Logger("GsonRequest");
private final Gson gson = new Gson();
private final Class<T> clazz;
private Response.Listener<T> listener;
/**
* Make a GET request and return a parsed object from JSON. Assumes
* {@link Request.Method#GET}.
*
* @param url
* URL of the request to make
* @param clazz
* Relevant class object, for Gson‘s reflection
*/
public MyGsonRequest(String url,HashMap<String, String> params,Class<T> clazz, Response.Listener<T> listener, Response.ErrorListener errorListener) {
super(Request.Method.GET, url, params,errorListener);
this.clazz = clazz;
this.listener = listener;
}
/**
* Make a GET request and return a parsed object from JSON. Assumes
* {@link Request.Method#GET}.
*
* @param url
* URL of the request to make
* @param clazz
* Relevant class object, for Gson‘s reflection
*/
public MyGsonRequest(String url, Class<T> clazz, Response.Listener<T> listener, Response.ErrorListener errorListener) {
super(Request.Method.GET, url, errorListener);
this.clazz = clazz;
this.listener = listener;
}
/**
* Like the other, but allows you to specify which {@link Request.Method} you want.
*
* @param method
* @param url
* @param clazz
* @param listener
* @param errorListener
*/
public MyGsonRequest(int method, String url, Class<T> clazz, Response.Listener<T> listener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.clazz = clazz;
this.listener = listener;
}
@Override
protected void deliverResponse(T response) {
if(listener != null){
listener.onResponse(response);
}
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
if(Looper.myLooper() == Looper.getMainLooper()){
mLogger.e("数据是 ==>在主线程中解析的~");
}else{
mLogger.e("数据不是 ==>在主线程中解析的~");
}
String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
JSONObject jsonObject = new JSONObject(json);
if(null != jsonObject && jsonObject.has("code") && jsonObject.getInt("code") == 200){
return Response.success(gson.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response));
}else{
return Response.error(new ParseError());
}
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
mLogger.e("JsonSyntaxException ==== ");
return Response.error(new ParseError(e));
} catch (JSONException e) {
return Response.error(new ParseError(e));
}
}
@Override
public void finish(final String tag) {
super.finish(tag);
listener = null;
}
}
?(3) 然后进行二次封装
/**
* 优化:
* (1)避免在主线程中解析json数据
* (2)添加了取消请求方法
*
* @param tag
* @param url
* @param params
* @param clazz
* @param callback
* @param <T>
*/
protected <T> void doRequest(String tag, String url, HashMap<String, String> params, final Class<?> clazz, final HttpCallback callback) {
String requestUrl = urlBuilder(url, params);
Logger.e("BaseTVApi", requestUrl);
callback.onLoading();
Response.Listener<T> successListener = new Response.Listener<T>() {
@Override
public void onResponse(T bean) {
if (bean != null) {
callback.onResponse(bean);
Logger.e("BaseTVApi", "request-->onResponse");
} else {
callback.onEmptyData();
Logger.e("BaseTVApi", "request-->onEmptyData");
}
}
};
Response.ErrorListener errorListener = new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
callback.onError();
Logger.e("BaseTVApi", "异常信息-->" + error.getMessage());
}
};
GsonRequest requestRequest = new GsonRequest(url, params, clazz, successListener, errorListener);
requestRequest.setTag(tag);
LeSportsApplication.getApplication().addHttpRequest(requestRequest);
}
? 打印log你会发现,你会发现数据解析是在子线程中执行的。
/**
* 网络请求优化,取消请求
* @param tag
*/
public void cancelRequest(String tag){
try {
mRequestQueue.cancelAll(tag);
}catch (Exception e){
Logger.e("LeSportsApplication","tag =="+ tag + "的请求取消失败");
}
}
(2) 在onStop中调用cancelRequest方法,最终会调用request的finish方法
@Override
public void finish(final String tag) {
super.finish(tag);
listener = null;
}
? (4) 在再看看GsonRequest 的父类Request的finish方法,我已经把mErrorListener干掉了。
public void finish(final String tag) {
if (mRequestQueue != null) {
mRequestQueue.finish(this);
}
if (MarkerLog.ENABLED) {
final long threadId = Thread.currentThread().getId();
if (Looper.myLooper() != Looper.getMainLooper()) {
// If we finish marking off of the main thread, we need to
// actually do it on the main thread to ensure correct ordering.
Handler mainThread = new Handler(Looper.getMainLooper());
mainThread.post(new Runnable() {
@Override
public void run() {
mEventLog.add(tag, threadId);
mEventLog.finish(this.toString());
}
});
return;
}
mEventLog.add(tag, threadId);
mEventLog.finish(this.toString());
} else {
long requestTime = SystemClock.elapsedRealtime() - mRequestBirthTime;
if (requestTime >= SLOW_REQUEST_THRESHOLD_MS) {
VolleyLog.d("%d ms: %s", requestTime, this.toString());
}
}
mErrorListener = null;
}
???? 总结:请求取消最终都会调用Request的finish方法,我们只要在这个方法中,把2个回调给干掉,问题就解决了。
private void requestUserSubscribesGame() {
uid = LoginUtils.getUid();
if (StringUtils.isStringEmpty(uid)) {
return;
}
UserTVApi.getInstance().getUserSubscribeGameId(TAG, uid, new SimpleCallback<ApiBeans.SubScribeListModel>() {
@Override
public void onResponse(ApiBeans.SubScribeListModel bean) {
SubScribeModel subScribeModel = bean.data;
if (subScribeModel != null) {
scribeGameEntrys = subScribeModel.getEntities();
requestHallData();
}
}
@Override
public void onError() {
Logger.e(TAG, "获取订阅信息失败...");
}
});
}
?
原文:http://1029457926.iteye.com/blog/2264167