我正在为凌空库编写一个反应式包装器,以便在我的应用中轻松发送http请求。这是班级:
/**
* Used to send a http GET/POST request.
*/
public class BasicRequest {
public static final String LOG_TAG = "BasicRequest";
public static final int GET_REQUEST = Request.Method.GET;
public static final int POST_REQUEST = Request.Method.POST;
private final int mRequestType;
private final String mServiceLocation;
private final Map<String, String> mParams;
/**
* Keeps track of all the request for this object. Will be helpful when we need to cancel
* the request when someone disposes the subscription.
*/
private List<StringRequest> mStringRequests = new ArrayList<>();
private Context mContext;
private int mRequestTimeout = BASIC_REQUEST_DEFAULT_TIMEOUT;
public BasicRequest(Context context,
String serviceLocation,
int requestType,
final Map<String, String> params) {
mContext = context;
mRequestType = requestType;
mServiceLocation = serviceLocation;
mParams = params;
}
private void fireRequest(final SingleEmitter<String> e) {
StringRequest stringRequest;
if(mRequestType == GET_REQUEST) {
stringRequest = new StringRequest(Request.Method.GET, mServiceLocation,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
e.onSuccess(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
e.onError(error);
}
});
} else {
stringRequest = new StringRequest(Request.Method.POST, mServiceLocation,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
e.onSuccess(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
e.onError(error);
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return mParams;
}
};
}
mStringRequests.add(stringRequest);
stringRequest.setRetryPolicy(new DefaultRetryPolicy(
mRequestTimeout,
ConnectionUtils.BASIC_REQUEST_DEFAULT_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
VolleyInstance.getInstance(mContext).addToRequestQueue(stringRequest);
}
/**
* Returns a Single observable for results. Queues the request on Subscription. Must be
* called only once during the lifetime of object. Calling multiple times will return null.
* Expect to get VolleyException in case of error.
* @return Single observable for String results. If it's is used for second time, it will
* return null.
*/
@Nullable
public Single<String> get() {
return Single.create(new SingleOnSubscribe<String>() {
@Override
public void subscribe(@NonNull SingleEmitter<String> e) throws Exception {
fireRequest(e);
}
}).doOnDispose(new Action() {
@Override
public void run() throws Exception {
for (StringRequest stringRequest: mStringRequests) {
stringRequest.cancel();
}
}
});
}
/**
* Set the request timeout for this request.
* @param requestTimeout time in milliseconds.
*/
public void setRequestTimeout(int requestTimeout) {
mRequestTimeout = requestTimeout;
}
现在的问题是当有人处理订阅时,所有与订阅相对应的请求都将被停止。有没有办法我只能停止处理订阅的请求?
我知道一旦实现它就会强制执行只能维护一个订阅,如果有人再次调用,则会返回缓存的观察者。是否有更好的方法根据订阅处理处理http请求?
答案 0 :(得分:1)
您无需在fireRequest
之外进行管理,SingleEmitter
完全具有setCancellable
方法,在那里进行取消,并且当有人处置时RxJava会确保调用它观察者。
添加fireRequest()
方法,然后移除doOnDispose
:
e.setCancellable(()-> stringRequest.cancel());