How to check Volley Request Queue is empty?And Request is finished?

你说的曾经没有我的故事 提交于 2020-04-13 07:15:14

问题


How to check Volley Request Queue is empty?And Request is finished?

After finishing of all requests I am trying to load ui but it's loading before requests response

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);

    }

回答1:


The Volley Lib does not provide a native method to check whether the request has already been finalized, this information is kept by a private property in an inner class of Lib. You can create your own control for this.

When I needed this functionality i implemented the following method to access CurrentRequests set through reflection.

I used a lib to facilitate this task. 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;
}

But it did not work efficiently for me, so I decided to keep a HashMap reference to all my request with a flag.




回答2:


Why don't you make changes in RequestQueue file as Volley is an open source project take advantage of this.I think instead of using reflection API we should refactor the code in library.

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;
}



回答3:


Declare globally counter variable, increment it when adding request to queue, decrement it in volley onResponse event, like this:

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
.
.

Nothing fancy, but works very efficiently for me.




回答4:


for single request there is two listener for it onResponse for success and onErrorResponse if request completed with exception

instead of fetch all records by loop fetch by single JSONRequest for better result with less time consumption.

further if have any issue kindly explain what do you exactly want to implement.




回答5:


How about just taking advantage of 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;
}
}

To use it ..

private int countRequestsInFlight(String tag){
    CountRequestsInFlight inFlight = new CountRequestsInFlight(tag);
    mRequestQueue.cancelAll(inFlight);
    return inFlight.getCount();
}

Since apply() always returns false, it doesn't affect the contents of the queue. No need to refactor the RequestQueue for this.




回答6:


Although I am late to answer I would like to share what I did to find out whether a request queue is empty or not.

I created a global variable files initialized to number of files putted in queeu and decremented it in onResposne. Then I added onRequestFinisedListener to RequestQueue and checked whether files is 0 or not.

Here is my code:

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();
            }
        }
    });
}



回答7:


Regarding to link You can control it and if there is no queue create a new one with this code:

Add a new one to queue.

public <T> void addToRequestQueue(Request<T> req) {
    req.setTag(TAG);
    getRequestQueue().add(req);

Control if queue is empty

public RequestQueue getRequestQueue() {
    if (mRequestQueue == null) {
        mRequestQueue = Volley.newRequestQueue(getApplicationContext());
    }

For more information see the link

EDIT:

For controlling request,failed or succeed use onResponseListener

private class ResponseListener implements Response.Listener{

@Override
public void onResponse(JSONObject response){

}
}


来源:https://stackoverflow.com/questions/25602298/how-to-check-volley-request-queue-is-emptyand-request-is-finished

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!