我试图了解如何在android中使用volley,所以在我的项目中我从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;
}
以下是MainActivity中调用方法getName()
的代码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);
}
});
答案 0 :(得分:1)
以下是调用函数String getName()
时会发生的情况:
JsonObjectRequest
,并将响应和错误侦听器传递给请求。请注意,在相应事件发生之前,侦听器不会执行。JsonObjectRequest
被添加到请求队列中,当线程池中的线程可用时执行。full_name
变量,并且您返回分配给它的最后一个值(这就是为什么当您再次单击该按钮时,您会在文本视图中获得一个名称)。full_name
分配新值。这是您下次调用getName()
时获得的值。 。 通常,像getName
这样的函数无法执行网络操作并立即返回其结果。它需要阻止直到它有来自服务器的响应(这在android中是prohibited)。或者,它可以在没有获取结果的情况下返回,并且具有一个回调函数(或一个监听器),当它可用时调用结果(这是Volley库中的一般方法)。
这意味着您必须在响应侦听器中setText
。我注意到你的网络请求RequestClass
有一个单独的类,为了保持你的设计原样,一个解决方案就是将监听器传递给getName()
函数(以及所有其他做网络的函数)在这个类中的东西),它可能看起来像这样:
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, "");
}
在你的活动中,你必须传递这样的听众:
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) {
}
});
}
});
作为更好的设计,您可能希望避免从活动中传递Volley
个侦听器(不必了解volley
),因此您可能希望定义自己的侦听器接口,覆盖并将其从活动传递到您的网络类(您实例化Response.Listener
,Response.ErrorListener
并覆盖它们以调用侦听器中的函数。)
答案 1 :(得分:0)
Volley库已被弃用,因此请勿使用Volley库。
Volley的最佳替代品是RetroFit库。
答案 2 :(得分:0)
试试这个
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();
}
});