Я использую AsyncTask в API для выполнения сетевых операций. В части пользовательского интерфейса есть кнопка, нажимающая на какой триггер API для выполнения задачи request/async. API выполняет обратный вызов, который обновляется из метода onPostExecute(). API получает нужные данные за один раз, когда onPostExecute() передает данные для обратного вызова. Все это работает хорошо. Но я получаю некоторые концептуальные проблемы при обновлении пользовательского интерфейса. Этого я хочу достичь: 1- Нажмите «Кнопка» в UI 2- Я хочу обновить строку ответа API для интерфейса. Эта строка ответа, которую я получаю после выполнения AsyncTask.Использование AsyncTask для реализации API и обновления результата для UI
Проблема в том, что API всегда возвращает null как ответ в текущем потоке выполнения. Как только поток пользовательского интерфейса выполняется, я вижу данные API/AsyncTask. Я знаю, что мне не хватает чего-то очень тривиального, но важного. Вы знаете, какой правильный способ обновить ответ API в пользовательском интерфейсе?
[Update]
Вот мой код 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;
}
}
Asy ncTask Код
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 после я нажимаю кнопку.
[Update 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().
Можете ли вы опубликовать код. Это даст нам лучшее понимание того, чего вы пытаетесь достичь. Мы сможем помочь вам лучше. –
как сказал Шобхит, нужен фрагмент кода, чтобы лучше понять вас. –
Опубликуйте свой код в asynctask & button нажмите –