如何更改 Volley 请求率

How to change Volley request rate

我正在向 Amazon Web Services 发出多个请求。我收到 503 错误,因为我太快发出了太多请求。我想知道如何设置 不同 请求之间的超时,而不是相同的请求。我 想要设置重试策略。我也寻找时间触发个人请求。我想计算请求 之间的间隔 。原因是我循环得如此之快并发出如此多的请求,以至于定时触发它们相当于同时提交它们。重点是 space 请求均匀

假设您有 Request 对象,在将请求添加到队列之前,您可以执行此操作

request.setRetryPolicy(new DefaultRetryPolicy(5000, 5, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

5000表示每次请求之间的时间间隔,单位ms 5 是您希望在超时之前发送请求的次数

为了有人看到,这是使用计时器手动隔离任务的方法

 Timer timer = new Timer();
    final Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            // Update UI here if u need
        }
    };
    TimerTask task = new TimerTask () {
        @Override
        public void run () {
           //send requests according to your logic here
        }
    };
    timer.schedule(task, 0, 60000); // 60000 = 1 min

由于你没有展示你是如何发出多个请求的,所以我建议你参考下面的示例,然后尝试应用到你的代码中。希望对您有所帮助!

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);            

        final RequestQueue queue = Volley.newRequestQueue(this);
        final String url = "http://google.com";
        final Handler handler = new Handler();
        for (int i = 0; i <= 5; i++) {
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    StringRequest request = new StringRequest(url, new Response.Listener<String>() {
                        @Override
                        public void onResponse(String response) {
                            Log.i("onResponse", response);                                
                        }
                    }, new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            Log.e("onErrorResponse", error.toString());
                        }
                    });    
                    queue.add(request);
                }
            }, 2000); // 2000 miliseconds
        }
    }

我也在为此苦苦挣扎,直到我得到了另一位开发人员的帮助。尝试这样的事情:

public class HTTP {
    String getUrl;
    Context context;
    YTVisualizer ytv;
    int numberOfCurrentRequests = 0;

    public HTTP(Context context, YTVisualizer ytv){
        this.context = context;
        this.ytv = ytv;
    }

    public void get(final String url) {
        numberOfCurrentRequests++;

        new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(250 * numberOfCurrentRequests);
                } catch(InterruptedException e) {
                    e.printStackTrace();
                }

                // Instantiate the RequestQueue.
                RequestQueue queue = Volley.newRequestQueue(context);

                String[] parts = url.split("=");
                final String key = parts[1];

                // Request a string response from the provided URL.
                StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                        new Response.Listener<String>() {
                            @Override
                            //runs in thread main
                            public void onResponse(String response) {
                                Log.i("Response", response);

                                String title = new String();

                                try {
                                    JSONObject obj = new JSONObject(response);
                                    Iterator<String> str = obj.keys();
                                    String key = str.next();
                                    title = obj.getString(key);

                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }

                                ytv.SetVideosFromHTTPClass(key, title, response);

                                numberOfCurrentRequests--;
                            }
                        }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(context, "Error: are you connected to the internet?", Toast.LENGTH_SHORT).show();
                        numberOfCurrentRequests--;
                    }
                });

                // Add the request to the RequestQueue.
                queue.add(stringRequest);
            }
        }).start();
    }
}

它暂停与当前请求量成正比。第一个睡 0.25 秒,第二个睡 0.5 秒,第三个睡 0.75 秒,依此类推。都按顺序安排了。

我知道这是一个老问题,但这里有一个用 Kotlin 编写的解决方案:

在 RequestQueue 的 class 中,您可以添加

val throttleTimeout : Long = 100L
private val throttleQueue : ArrayBlockingQueue<Request<*>> = ArrayBlockingQueue(100);
private val throttleThread = Thread {
    while(true){
        val rqst = throttleQueue.take()
        requestQueue?.add(rqst)
        Thread.sleep(throttleTimeout)
    }
}

fun <T> addToThrottledRequestQueue(request: Request<T>, tag: String){
    request.tag = if (TextUtils.isEmpty(tag)) TAG else tag
    throttleQueue.put(request)
}

并且确保在 class 初始化中启动线程。您还可以将其与创建非节流请求的函数混合并将它们混合在一起。

fun <T> addToRequestQueue(request: Request<T>, tag: String) {
    request.tag = if (TextUtils.isEmpty(tag)) TAG else tag
    requestQueue?.add(request)
}

addToThrottledRequestQueue 函数将确保这些请求受到限制,而其他请求可以自由流动。