Google 致力于为黑人社区推动种族平等。查看具体举措

发送简单请求

大体上讲,您可以通过创建 RequestQueue 并向其传递 Request 对象以使用 Volley。RequestQueue 管理用于运行网络操作、向缓存读写数据以及解析响应的工作器线程。请求负责解析原始响应,而 Volley 负责将已解析的响应调度回主线程以供传送。

本课程介绍了如何使用 Volley.newRequestQueue 便捷方法发送请求,该方法会为您设置一个 RequestQueue。如需了解如何自行设置 RequestQueue,请参阅下一课 设置 RequestQueue

本课程还介绍了如何将请求添加到 RequestQueue 以及如何取消请求。

添加 INTERNET 权限

如需使用 Volley,您必须向应用清单添加 android.permission.INTERNET 权限。否则,应用将无法连接到网络。

使用 newRequestQueue

Volley 提供了一种便捷方法 Volley.newRequestQueue,该方法会使用默认值为您设置一个 RequestQueue,并启动该队列。例如:

Kotlin

    val textView = findViewById<TextView>(R.id.text)
    // ...

    // Instantiate the RequestQueue.
    val queue = Volley.newRequestQueue(this)
    val url = "http://www.google.com"

    // Request a string response from the provided URL.
    val stringRequest = StringRequest(Request.Method.GET, url,
            Response.Listener<String> { response ->
                // Display the first 500 characters of the response string.
                textView.text = "Response is: ${response.substring(0, 500)}"
            },
            Response.ErrorListener { textView.text = "That didn't work!" })

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

Java

    final TextView textView = (TextView) findViewById(R.id.text);
    // ...

    // Instantiate the RequestQueue.
    RequestQueue queue = Volley.newRequestQueue(this);
    String url ="http://www.google.com";

    // Request a string response from the provided URL.
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            // Display the first 500 characters of the response string.
            textView.setText("Response is: "+ response.substring(0,500));
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            textView.setText("That didn't work!");
        }
    });

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

Volley 始终在主线程上传送已解析的响应。在主线程上运行便于使用接收的数据填充界面控件,因为您可以直接从响应处理程序随意修改界面控件。对于库提供的许多重要语义(特别是与取消请求相关的语义)来说,这尤为重要。

如需了解如何自行设置 RequestQueue(而不是使用 Volley.newRequestQueue 便捷方法),请参阅设置 RequestQueue

发送请求

如需发送请求,您只需构建一个请求,并使用 add() 将其添加到 RequestQueue,如上文所示。您添加请求后,它会经过管道,得到处理,然后其原始响应会被解析并传送。

您调用 add() 时,Volley 会运行一个缓存处理线程和一个网络调度线程池。将请求添加到队列后,缓存线程会拾取该请求并对其进行分类:如果该请求可以通过缓存处理,系统会在缓存线程上解析缓存的响应,并在主线程上传送解析后的响应。如果该请求无法通过缓存处理,则系统会将其放置到网络队列中。第一个可用的网络线程会从队列中获取该请求,执行 HTTP 事务,在工作器线程上解析响应,将响应写入缓存,然后将解析后的响应发送回主线程以供传送。

请注意,阻塞 I/O 和解析/解码等开销大的操作都是在工作器线程上完成的。您可以添加来自任意线程的请求,但响应始终会在主线程上传送。

图 1 展示了请求的生命周期:

系统栏

图 1. 请求的生命周期。

取消请求

如需取消请求,请在 Request 对象上调用 cancel()。取消请求后,Volley 可以确保您的响应处理程序永远不会被调用。实际上,这意味着您可以在 Activity 的 onStop() 方法中取消所有待处理的请求,并且无论是否已调用 onSaveInstanceState(),您都无需通过检查 getActivity() == null 丢弃响应处理程序,或其他防御性样板。

如需利用此行为,您通常需要跟踪所有传输中的请求,以便能够在适当的时间取消它们。有一种更简单的方法:您可以将一个标记对象与每个请求相关联。然后,使用该标记提供要取消的请求范围。例如,您可以使用代表其发出请求的 Activity 标记所有相应请求,然后从 onStop() 调用 requestQueue.cancelAll(this)。同样,您可以标记 ViewPager 标签中的所有缩略图请求(使用其各自的标签),并在用户执行滑动操作时取消,以确保新标签不会被来自其他标签的请求阻止。

以下是为标记使用字符串值的示例:

  1. 定义标记并将其添加到请求中。

    Kotlin

        val TAG = "MyTag"
        val stringRequest: StringRequest // Assume this exists.
        val requestQueue: RequestQueue? // Assume this exists.
    
        // Set the tag on the request.
        stringRequest.tag = TAG
    
        // Add the request to the RequestQueue.
        requestQueue?.add(stringRequest)
        

    Java

        public static final String TAG = "MyTag";
        StringRequest stringRequest; // Assume this exists.
        RequestQueue requestQueue;  // Assume this exists.
    
        // Set the tag on the request.
        stringRequest.setTag(TAG);
    
        // Add the request to the RequestQueue.
        requestQueue.add(stringRequest);
        
  2. 在 Activity 的 onStop() 方法中,取消所有具有此标记的请求。

    Kotlin

        protected fun onStop() {
            super.onStop()
            requestQueue?.cancelAll(TAG)
        }
        

    Java

        @Override
        protected void onStop () {
            super.onStop();
            if (requestQueue != null) {
                requestQueue.cancelAll(TAG);
            }
        }
        

    取消请求时应小心谨慎。如果您依赖响应处理程序推进状态或启动其他流程,则需要考虑这一点。再次声明,取消后响应处理程序将不会被调用。