如何检查Volley Request Queue是空的?请求已完成?

时间:2014-09-01 09:02:58

标签: android android-volley

如何检查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);

    }

7 个答案:

答案 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){

}
}