Я создал вспомогательный класс для обработки всех моих HTTP-вызовов в моем приложении. Это простая одноэлементная оболочка для okhttp, которая выглядит так (я опустил некоторые несущественные части):
public class HttpUtil {
private OkHttpClient client;
private Request.Builder builder;
...
public void get(String url, HttpCallback cb) {
call("GET", url, cb);
}
public void post(String url, HttpCallback cb) {
call("POST", url, cb);
}
private void call(String method, String url, final HttpCallback cb) {
Request request = builder.url(url).method(method, method.equals("GET") ? null : new RequestBody() {
// don't care much about request body
@Override
public MediaType contentType() {
return null;
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
}
}).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, Throwable throwable) {
cb.onFailure(null, throwable);
}
@Override
public void onResponse(Response response) throws IOException {
if (!response.isSuccessful()) {
cb.onFailure(response, null);
return;
}
cb.onSuccess(response);
}
});
}
public interface HttpCallback {
/**
* called when the server response was not 2xx or when an exception was thrown in the process
* @param response - in case of server error (4xx, 5xx) this contains the server response
* in case of IO exception this is null
* @param throwable - contains the exception. in case of server error (4xx, 5xx) this is null
*/
public void onFailure(Response response, Throwable throwable);
/**
* contains the server response
* @param response
*/
public void onSuccess(Response response);
}
}
Затем в моем основном действии я использую этот вспомогательный класс:
HttpUtil.get(url, new HttpUtil.HttpCallback() {
@Override
public void onFailure(Response response, Throwable throwable) {
// handle failure
}
@Override
public void onSuccess(Response response) {
// <-------- Do some view manipulation here
}
});
onSuccess
генерирует исключение при запуске кода:
android.view.ViewRootImpl $CalledFromWrongThreadException: только оригинальный поток, создавший иерархию представлений, может коснуться его представлений.
С моей точки зрения, обратные вызовы Okhttp работают в основном потоке, так почему я могу получить эту ошибку?
** Как и примечание, я создал интерфейс HttpCallback
для оболочки класса Okhttp Callback
, потому что я хотел изменить поведение onResponse
и onFailure
, чтобы я мог объединить логику обработки неудачных ответов из-за исключений i/o и неудачных ответов из-за проблем с сервером.
Спасибо.