如何检查Volley Request Queue是空的?请求已完成?
在完成所有请求后,我尝试加载ui,但它在请求响应之前加载
for (i = 1; i < obj.length; i++) {
String apiString = myGlobalClass.getApiUrl();
callRequest(apiString);
}
private callRequest(String apiString) {
// TODO Auto-generated method stub
request = new StringRequest(Request.Method.GET, apiString,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// TODO Auto-generated method stub
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
queue.add(request);
}
答案 0 :(得分:3)
为什么不在RequestQueue文件中进行更改,因为Volley是一个开源项目,利用这一点。我认为我们不应该使用反射API来重构库中的代码。
public boolean isRequestInQueue(final String tag) {
return isRequestInQueue(new RequestFilter() {
@Override
public boolean apply(Request<?> request) {
return request.getTag() == tag;
}
});
}
private boolean isRequestInQueue(RequestFilter requestFilter){
synchronized (mCurrentRequests) {
for (Request<?> request : mCurrentRequests) {
if (requestFilter.apply(request)) {
return true;
}
}
}
return false;
}
答案 1 :(得分:1)
Volley Lib没有提供本地方法来检查请求是否已经完成,此信息由Lib的内部类中的私有属性保存。 您可以为此创建自己的控件。
当我需要此功能时,我实现了以下方法来通过反射访问CurrentRequests。
我用lib来完成这项任务。 Mirror
public boolean isPendingToRequest( final Object tag ) {
final Object mObject = new Mirror().on( this.requestQueue ).get().field( "mCurrentRequests" );
final Set<Request<?>> mCurrentRequests = ( Set<Request<?>> ) mObject;
for ( final Request<?> request : mCurrentRequests ) {
Log.d( "tagIsPendingToRequest ", "tag: " + request.getTag() );
if ( request.getTag().equals( tag ) ) {
Log.d( "tagIsPendingToRequest ", "Pendingtag: " + request.getTag() + " mytag:" + tag );
return true;
}
}
return false;
}
但它对我没有效率,所以我决定用一个标志保留一个HashMap引用我的所有请求。
答案 2 :(得分:1)
声明全局计数器变量,在将请求添加到队列时递增,在凌空onResponse事件中递减,如下所示:
private int numRequests = 0; //counts volley requests
.
.
.
StringRequest stringRequest = new StringRequest(Request.Method.POST, ContactActivity.URL_SAVE_CONTACT,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONObject obj = new JSONObject(response);
if (!obj.getBoolean("error")) {
}
} catch (JSONException e) {
e.printStackTrace();
}
numRequests--; //decrement counter
if(numRequests==0){
//do your stuff here
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("name", name);
return params;
}
};
VolleySingleton.getInstance(this).addToRequestQueue(stringRequest);
numRequests++; //increment counter
.
.
没什么,但是对我来说非常有效。
答案 3 :(得分:0)
对于单个请求,有两个监听器onResponse用于成功,而onErrorResponse用于请求已完成且异常
而不是通过单个JSONRequest循环获取来获取所有记录,以获得更好的结果,同时消耗更少的时间。
如果有任何问题,请进一步解释您究竟想要实施的内容。
答案 4 :(得分:0)
如何利用cancelAll(RequestFilter)?
public class CountRequestsInFlight implements RequestQueue.RequestFilter {
Object tag;
int count = 0;
public CountRequestsInFlight(Object tag) {
this.tag = tag;
}
@Override
public boolean apply(Request<?> request) {
if (request.getTag().equals(tag)) {
count++;
}
return false; // always return false.
}
public int getCount() {
return count;
}
}
使用它..
private int countRequestsInFlight(String tag){
CountRequestsInFlight inFlight = new CountRequestsInFlight(tag);
mRequestQueue.cancelAll(inFlight);
return inFlight.getCount();
}
由于apply()始终返回false,因此不会影响队列的内容。无需为此重构RequestQueue。
答案 5 :(得分:0)
虽然我迟到了,但我想分享我所做的事情,以确定请求队列是否为空。
我创建了一个全局变量files
,该变量初始化为在queeu中放置的文件数,并在onResposne
中递减。然后我将onRequestFinisedListener
添加到RequestQueue
并检查files
是否为0
。
这是我的代码:
private int files;
public void downloadAllChapters() {
files = bookData.size();
final ProgressDialog progressDialog = new ProgressDialog(context);
progressDialog.setCancelable(false);
progressDialog.setTitle(Constants.APP_NAME);
progressDialog.setMessage("Downloading " + files + " files... Please wait");
progressDialog.show();
final RequestQueue requestQueue = Volley.newRequestQueue(context);
for (final NewLibraryData s : bookData) {
requestQueue.add(new StringRequest(Request.Method.GET, Constants.booksBaseURL + s.slug, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (context == null) return;
try {
File file = new File(Environment.getExternalStorageDirectory() + "/" + Constants.APP_NAME + "/books/" + s.slug);
if (!file.exists()) {
boolean newFile = file.createNewFile();
if (!newFile) {
Toast.makeText(context, "Unable to save file to SD card, please try again", Toast.LENGTH_SHORT).show();
}
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(response.getBytes());
fos.close();
} catch (Exception e) {
e.printStackTrace();
progressDialog.hide();
Toast.makeText(context, "Some error occurred, please try again", Toast.LENGTH_SHORT).show();
}
files--;
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (context == null) return;
Toast.makeText(context, "Internet not Available", Toast.LENGTH_SHORT).show();
progressDialog.hide();
}
}));
}
requestQueue.addRequestFinishedListener(new RequestQueue.RequestFinishedListener<StringRequest>() {
@Override
public void onRequestFinished(Request<StringRequest> request) {
if (files == 0 && progressDialog.isShowing()) {
progressDialog.hide();
Toast.makeText(context, "Download completed successfully", Toast.LENGTH_SHORT).show();
}
}
});
}
答案 6 :(得分:-3)
关于link 您可以控制它,如果没有队列,则使用以下代码创建一个新队列:
添加一个新队列。
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
控制队列是否为空
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
有关详细信息,请参阅link
编辑:
用于控制请求,失败或成功使用onResponseListener
private class ResponseListener implements Response.Listener{
@Override
public void onResponse(JSONObject response){
}
}