#java #rest #retrofit
#java #rest #модернизация
Вопрос:
У меня есть модифицированный интерфейс, который определяет метод с обратным вызовом, подобный этому :
public interface ApiManagerService {
@GET("/users/")
void getUsers(Callback<List<GitHubMember>>);
}
GitHubMember
это просто POJO с 3 полями: id, login и URL. Я создал класс под названием ResponseHandler, куда я могу перенести ответ из обратного вызова. Вот как это определить :
public class ResponseHandler<T> {
private T response;
private RESPONSE_CODE responseCode;
private String detail;
public static enum RESPONSE_CODE {
OK, // if request suceed
APP_ERROR, //technical error for instance network
TECHNICAL_ERROR // app technical error
}
//getters and setters
Вот как я использую этот класс с методом getUsers :
public ResponseHandler<List<GitHubMember>> getUsers() {
ResponseHandler<List<GitHubMember>> handler = new ResponseHandler<List<GitHubMember>>();
apiManagerService.getUsers(new Callback<List<GitHubMember>> cb) {
@Override
public void success(List<GitHubMember> users, Response response) {
responseHandler.setResponse(users);
responseHandler.setResponseCode(ResponseHandler.RESPONSE_CODE.OK);
}
@Override
public void failure(RetrofitError error) {
try {
handler.setResponseCode(ResponseHandler.RESPONSE_CODE.APP_ERROR);
responseHandler.setDetail(error.toString());
}catch (Exception e){
handler.setResponseCode(ResponseHandler.RESPONSE_CODE.TECHNICAL_ERROR);
responseHandler.setDetail(e.getMessage());
}
}
}
return handler;
}
Проблема, с которой я сталкиваюсь, заключается в том, что после выполнения этого метода и ввода обратного вызова все поля в ResponseHandler равны нулю. Я полностью уверен, что обратные вызовы выполняются, потому что я установил точки останова в обратном вызове во время отладки.
Объект apiManagerService правильно инициализирован с помощью класса RestAdapter.
Как я могу решить эту проблему?
Ответ №1:
apiManagerService.getUsers()
только инициирует сетевой запрос и возвращает. Обратный вызов вызывается после того, как сеть ответила в фоновом потоке. Таким образом, к моменту return handler
выполнения handler
все еще пусто. Более того, даже если после обратного вызова будет выполнен какой-либо оператор возврата, вы можете не увидеть изменений, внесенных в общие переменные (поля обработчика) фоновым потоком из-за ограничений модели памяти Java.
Комментарии:
1. Есть идеи, как решить эту проблему? Я мог бы использовать countdownlatch для ожидания обратного вызова?
2. @Dimitri для этого вы можете использовать шину событий: опубликовать результат обратного вызова и обработать его в методе подписчика в Activity или другом компоненте. В качестве примера вы можете использовать Otto или EventBus.