gpt4 book ai didi

java - 为什么这个 Android Volley 请求永远不会完成?

转载 作者:行者123 更新时间:2023-12-02 02:25:18 25 4
gpt4 key购买 nike

使用 Volley HTTP 库在 Android Activity 中考虑此代码。 HTTP 请求永远不会完成。它既不会收到正常响应,也不会收到错误响应。但如果 while (!done) block 被注释掉,那么一切都会正常完成。这让我感到惊讶,因为我使用 Volley 创建了一个 RequestQueue,其中包含一个线程池,其中使用完全独立的线程来执行 HTTP 请求。那么,如果该线程正在 hibernate ,为什么请求永远不会完成?

代码:

package com.adobe.instore.activities;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import com.adobe.instore.R;
import com.adobe.instore.Urls;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONObject;

public class VolleyTestActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_volley_test);
}

private static boolean done = false;
protected void makeRequest(View v) {
Log.i(getLocalClassName(), "Request");

RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
queue.start();
queue.add(new JsonObjectRequest(Request.Method.GET, Urls.STATIC_URL + "/profiles.json", null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.i(getLocalClassName(), "Response");
done = true;
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(getLocalClassName(), "Error");
}
}));

Log.i(getLocalClassName(), "Awaiting completion");
while(!done) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.i(getLocalClassName(), "Done");
}
}

最佳答案

View 在主线程(有时称为 UI 线程)中呈现。您创建的循环会阻止渲染和后续的其他代码。从技术上讲,调用 Thread.sleep(...); 是个坏主意。在这个线程中,因为很多事情都会受到影响。 Volley 是一个 http 库,旨在让您的生活变得更简单,无需显式调用您自己的线程。

在 Volley 中,所有网络和缓存调度都是在单独的线程(幕后)中完成的,而响应则发送回主线程。这只是意味着 onResponseonError发生在主线程中。

为了让它更简单,你可以这样做:

public class VolleyTestActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_volley_test);
}

public void makeRequest(View v) {
Log.i(getLocalClassName(), "Request");

RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
queue.start();
queue.add(new JsonObjectRequest(Request.Method.GET, Urls.STATIC_URL + "/profiles.json", null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.i(getLocalClassName(), "Response");
Log.i(getLocalClassName(), "Done");
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(getLocalClassName(), "Error");
}
}));

Log.i(getLocalClassName(), "Awaiting completion");
}
}

此外while()Thread.sleep保持线程忙碌。因此,在循环完成之前,主线程中排队的任何执行都是无法访问的(但它不会发生)。您可能会认为onResponse可以绕过无限循环吗?答案是不;因为onResponse由主线程而不是后台线程排队。为了说明请看下图: enter image description here

图 1:Android Volley 内部架构(图片来自文档)

如果您查看显示在主线程上传递的已解析响应的框,该框颜色为蓝色,表示调用它的是主线程(简单来说,这意味着 onResponseonError 是由主线程调用)除非它是橙色或绿色,否则循环将被您的 boolean 值绕过。

关于java - 为什么这个 Android Volley 请求永远不会完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47878742/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com