Volley Request 将之前的值设置为 TextView
Volley Request Sets the previous value to TextView
我想了解 volley 在 android 中是如何使用的,所以在我的项目中,我正在查询 http://uinames.com/api/?amount=1
中的单个名称
在应用程序中,我有一个按钮调用函数来发出请求,然后将其设置到 TextView。同样出于调试目的,我记录了来自 url
的响应。单击按钮时,logcat 中可以正确看到响应,但直到下次单击按钮时,文本才会设置到 TextView。
这是 JsonObjectRequest 的代码
public String getName() {
JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.GET,
URL, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
full_name = response.getString(name) + " " + response.getString(last);
Log.d(TAG, full_name);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
AppController.getInstance().addToRequestQueue(objectRequest, "");
return full_name;
}
以下是调用 getName() 方法的 MainActivity 中的代码
mButton = (Button) findViewById(R.id.btn);
mTextView = (TextView) findViewById(R.id.text);
final RequestClass newReq = new RequestClass();
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
name = newReq.getName();
mTextView.setText(name);
}
});
Volley 库已弃用,因此请勿使用 Volley 库。
Volley 的最佳替代品是 RetroFit 库。
这样试试
public void getName() {
JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.GET,
URL, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
full_name = response.getString("name") + " " + response.getString("last");
runOnUiThread(new Runnable() {
@Override
public void run() {
//Your code to run in GUI thread here
mTextView.setText(full_name);
}
});
Log.d(TAG, full_name);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
AppController.getInstance().addToRequestQueue(objectRequest, "");
}
mButton = (Button) findViewById(R.id.btn);
mTextView = (TextView) findViewById(R.id.text);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getName();
}
});
调用函数 String getName()
时会发生以下情况:
- 构造了一个
JsonObjectRequest
,并将响应和错误侦听器传递给请求。请注意,监听器只有在相应事件发生后才会执行。
JsonObjectRequest
被添加到请求队列中,当线程池中的线程可用时执行。
- 直到现在
full_name
变量还没有被触及,你 return 分配给它的最后一个值(这就是为什么当你再次点击按钮时,你会在你的文本视图)。
- 您的请求得到响应,并且在您的函数 returned 之后调用侦听器为
full_name
分配新值。这是您在下次调用 getName()
时获得的值。 . .
一般来说,像getName
这样的函数不能立即执行网络操作,return其结果。它要么需要 阻塞 直到它收到来自服务器的响应(这是 android 中的 prohibited)。或者,它可以 return 尚未获取结果,并有一个回调函数(或监听器),当结果可用时调用该回调函数(这是 Volley 库中的通用方法)。
这意味着您必须在响应监听器中 setText
。我注意到您的网络请求 RequestClass
有一个单独的 class,为了保持您的设计不变,一种解决方案是将侦听器传递给 getName()
函数(以及所有其他在此 class 中执行网络操作的函数),它可能看起来像这样:
public void getName(Response.Listener<JSONObject> responseListener,
Response.ErrorListener errorListener) {
JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.GET,
URL, null, responseListener, errorListener);
AppController.getInstance().addToRequestQueue(objectRequest, "");
}
并且在你的 activity 中,你必须像这样传递听众:
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
name = newReq.getName(
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
String full_name = response.getString("name") + " " + response.getString("last");
mTextView.setText(full_name);
Log.d(TAG, full_name);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
}
});
作为更好的设计,您可能希望避免从 activity 传递 Volley
侦听器(它不必知道任何有关 volley
的信息),因此您可能希望定义您自己的侦听器接口,覆盖并将其从 activity 传递到您的网络 class(在其中实例化您的 Response.Listener
、Response.ErrorListener
并覆盖它们以在您的侦听器中调用函数).
我想了解 volley 在 android 中是如何使用的,所以在我的项目中,我正在查询 http://uinames.com/api/?amount=1
在应用程序中,我有一个按钮调用函数来发出请求,然后将其设置到 TextView。同样出于调试目的,我记录了来自 url
的响应。单击按钮时,logcat 中可以正确看到响应,但直到下次单击按钮时,文本才会设置到 TextView。
这是 JsonObjectRequest 的代码
public String getName() {
JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.GET,
URL, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
full_name = response.getString(name) + " " + response.getString(last);
Log.d(TAG, full_name);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
AppController.getInstance().addToRequestQueue(objectRequest, "");
return full_name;
}
以下是调用 getName() 方法的 MainActivity 中的代码
mButton = (Button) findViewById(R.id.btn);
mTextView = (TextView) findViewById(R.id.text);
final RequestClass newReq = new RequestClass();
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
name = newReq.getName();
mTextView.setText(name);
}
});
Volley 库已弃用,因此请勿使用 Volley 库。
Volley 的最佳替代品是 RetroFit 库。
这样试试
public void getName() {
JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.GET,
URL, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
full_name = response.getString("name") + " " + response.getString("last");
runOnUiThread(new Runnable() {
@Override
public void run() {
//Your code to run in GUI thread here
mTextView.setText(full_name);
}
});
Log.d(TAG, full_name);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
AppController.getInstance().addToRequestQueue(objectRequest, "");
}
mButton = (Button) findViewById(R.id.btn);
mTextView = (TextView) findViewById(R.id.text);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getName();
}
});
调用函数 String getName()
时会发生以下情况:
- 构造了一个
JsonObjectRequest
,并将响应和错误侦听器传递给请求。请注意,监听器只有在相应事件发生后才会执行。 JsonObjectRequest
被添加到请求队列中,当线程池中的线程可用时执行。- 直到现在
full_name
变量还没有被触及,你 return 分配给它的最后一个值(这就是为什么当你再次点击按钮时,你会在你的文本视图)。 - 您的请求得到响应,并且在您的函数 returned 之后调用侦听器为
full_name
分配新值。这是您在下次调用getName()
时获得的值。 . .
一般来说,像getName
这样的函数不能立即执行网络操作,return其结果。它要么需要 阻塞 直到它收到来自服务器的响应(这是 android 中的 prohibited)。或者,它可以 return 尚未获取结果,并有一个回调函数(或监听器),当结果可用时调用该回调函数(这是 Volley 库中的通用方法)。
这意味着您必须在响应监听器中 setText
。我注意到您的网络请求 RequestClass
有一个单独的 class,为了保持您的设计不变,一种解决方案是将侦听器传递给 getName()
函数(以及所有其他在此 class 中执行网络操作的函数),它可能看起来像这样:
public void getName(Response.Listener<JSONObject> responseListener,
Response.ErrorListener errorListener) {
JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.GET,
URL, null, responseListener, errorListener);
AppController.getInstance().addToRequestQueue(objectRequest, "");
}
并且在你的 activity 中,你必须像这样传递听众:
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
name = newReq.getName(
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
String full_name = response.getString("name") + " " + response.getString("last");
mTextView.setText(full_name);
Log.d(TAG, full_name);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
}
});
作为更好的设计,您可能希望避免从 activity 传递 Volley
侦听器(它不必知道任何有关 volley
的信息),因此您可能希望定义您自己的侦听器接口,覆盖并将其从 activity 传递到您的网络 class(在其中实例化您的 Response.Listener
、Response.ErrorListener
并覆盖它们以在您的侦听器中调用函数).