ネットワーク操作を実行するために API で AsyncTask を使用しています。UI 部分にはボタンがあり、クリックすると API がリクエスト/非同期タスクを実行します。API は onPostExecute() メソッドから更新されるコールバックを実装しています。onPostExecute() がデータをコールバックに渡すと、API は適切なデータを取得します。これはすべてうまくいきます。しかし、UI の更新中に概念的な問題が発生しています。これは私が達成したいことです: 1- UI の「ボタン」をクリックします 2- API の応答文字列を UI に更新したいです。AsyncTask を実行した後に取得するこの応答文字列。
問題は、API が現在の実行スレッドの応答として常に null を返すことです。UI スレッドが完了すると、API/AsyncTask データが入ってくるのがわかります。非常に些細なことですが、重要なものが欠けていることがわかります。UI で API 応答を更新する正しい方法を知っていますか?
[アップデート]
APIを介して非同期タスクをトリガーするボタンをクリックすることを含む私のUIコードは次のとおりです(サーバー応答を取得するためのコールバックを実装する別のクラス)
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 というコールバックをもう 1 つ定義し、アクティビティをそれに登録すると、問題が解決することがわかりました。
UICallback:
public interface UICallback {
public void onFailure(String response);
void onSuccess(String response) throws IOException;
}
Activity にそれを実装させる:
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);
}
}
誰もこれよりも良い解決策を持っていますか? 追加のコールバックを実装するアクティビティのアイデアは本当に好きではありません。api.getResponseString() だけで、データのフェッチが完了したら、API 自体がサーバーの応答を配信できれば、最高だったでしょう。