我在API中使用AsyncTask来执行网络操作。在UI部分有一个按钮,单击该按钮会触发API执行请求/异步任务。 API正在实现从onPostExecute()方法更新的回调。一旦onPostExecute()将数据传递给回调,API就会获得正确的数据。这一切都很好。但是在更新到UI时我遇到了一些概念性问题。这就是我想要实现的目标: 1-在UI上单击“按钮” 2-我想将API的响应字符串更新为UI。执行AsyncTask后得到的响应字符串。
问题是API总是在当前执行线程中返回null作为响应。一旦UI线程完成,我就会看到API / AsyncTask数据进入。我知道我遗漏了一些非常微不足道的东西,但很重要。您知道在UI上更新API响应的正确方法吗?
[更新]
这是我的UI代码,其中包括单击按钮通过API触发异步任务(只是另一个实现回调以获取服务器响应的类)
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
API api = new API();
Request request = new Request();
request.setUrl("http://www.example.com/");
api.fetch(request);
try {
//It doesn't matter how much you wait here to return the response.
//Response from task doesn't return in this thread.
//If I click another button say "refresh" to refresh the data, then api.getResponseString() shows the response from server.
Thread.sleep(2000);
//api.getResponseString() returns null. I expect it to return data just retrieved from server
String text = api.getResponseString();
System.out.println("Text: " + text);
textView.setText(text);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
API代码
public class Api implements ResponseCallbacks {
String responseString = null;
public void fetch(Request request) {
makeRequest(request, this);
}
public void makeRequest(Request request,
final ResponseCallbacks responseCallbacks) {
MyTask asyncTask = new MyTask();
asyncTask.setResponseCallbacks(responseCallbacks);
asyncTask.execute(request);
}
@Override
public void onSuccess(Response response) throws IOException {
if (response.isSuccess()) {
responseString = "Success";
} else {
responseString = "Failed";
}
}
public String getResponseString() {
return responseString;
}
}
AsyncTask代码
public class MyTask extends AsyncTask {
private ResponseCallbacks responseCallbacks;
public MyTask() {}
public void setResponseCallbacks(ResponseCallbacks callbacks) {
this.responseCallbacks = callbacks;
}
@Override
protected Response doInBackground(Request... params) {
Request request = params[0];
Response Response = null;
try {
//Make Http call and gets response from remote server here...
} catch (Exception e) {
}
return response;
}
protected void onPostExecute(Response response) {
if (response.isSuccess()) {
try {
if (response.isSuccess()) {
callbacks.onSuccess(response);
}
} catch (Exception e) {
callbacks.onFailure(response);
}
}
}
}
我想要的是在点击按钮后更新textView中从服务器返回的文本。
[更新2] 显然,我发现如果我再定义一个回调说UICallback并让我的活动注册它,解决了这个问题。
UICallback:
public interface UICallback {
public void onFailure(String response);
void onSuccess(String response) throws IOException;
}
让活动实现它:
public class MainActivity extends Activity implements UICallback {
.......
api = new NetApi();
api.setUICallbacks(this);
.......
@Override
public void onSuccess(String response) throws IOException {
String text = api.getResponseString();
//works !
textView.setText(text);
}
}
有没有人有比这更好的解决方案?我真的不喜欢Activity实现额外回调的想法。如果我的api本身只需通过api.getResponseString()完成获取数据就可以提供服务器响应,这本来是很棒的。
答案 0 :(得分:1)
我的猜测是,你正在寻找的是runOnUIThread。
如果在onPostExecute
中使用此功能,则可以刷新UI数据而无需注册回调等等。像这样:
protected void onPostExecute(Response response) {
if (response.isSuccess()) {
try {
if (response.isSuccess()) {
runOnUiThread(new Runnable() {
public void run() {
textView.setText(text);
}
});
}
} catch (Exception e) {
callbacks.onFailure(response);
}
}
}
同步替代方法是在主线程中使用Runnable。您必须立即重新定义MyTask以实施Runnable
和join
。喜欢这个
Thread asyncTask = new Thread(MyTask());
asyncTask.start();
asyncTask.join();//gets called as soon as the task ends
MyTask将是
public class MyTask implements Runnable{
public void run(){
//do whatever you need to do
}
}