메인 스레드의 Okhttp 응답 콜백
내 앱에서 모든 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
그래서 나는 예외 오 인해 난에 실패 응답 / 인한 서버 문제로 실패 응답을 처리하는 로직을 결합 할 수있다.
감사.
From my understanding, Okhttp callbacks run on the main thread so why do I get this error ?
This is not true. Callbacks run on a background thread. If you want to immediately process something in the UI you will need to post to the main thread.
Since you already have a wrapper around the callback you can do this internally in your helper so that all HttpCallback
methods are invoked on the main thread for convenience.
As Jake Wharton suggested, I had to run the callbacks on the main thread explicitly.
So I wrapped the calls to the callbacks with Runnable
like this:
private void call(String method, String url, final HttpCallback cb) {
...
client.newCall(request).enqueue(new Callback() {
Handler mainHandler = new Handler(context.getMainLooper());
@Override
public void onFailure(Request request,final Throwable throwable) {
mainHandler.post(new Runnable() {
@Override
public void run() {
cb.onFailure(null, throwable);
}
});
}
@Override
public void onResponse(final Response response) throws IOException {
mainHandler.post(new Runnable() {
@Override
public void run() {
if (!response.isSuccessful()) {
cb.onFailure(response, null);
return;
}
cb.onSuccess(response);
}
});
}
});
}
I know it's an old question, but recently I encountered the same issue. If you need to update any view, you will need to use runOnUiThread()
or post the result back on the main thread.
HttpUtil.get(url, new Callback() { //okhttp3.Callback
@Override
public void onFailure(Call call, IOException e) { /* Handle error **/ }
@Override
public void onResponse(Call call, Response response) throws IOException {
String myResponse = response.body().string();
//Do something with response
//...
MyActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
//Handle UI here
findViewById(R.id.loading).setVisibility(View.GONE);
}
});
}
});
According to Retrofit documentation Callback methods are executed on UI thread by default until you provide a callback executor to Retrofit OR when using custom method return types using CallAdapterFactory
참고URL : https://stackoverflow.com/questions/24246783/okhttp-response-callbacks-on-the-main-thread
'IT TIP' 카테고리의 다른 글
Pandas의 큰 상관 행렬에서 가장 높은 상관 쌍을 나열 하시겠습니까? (0) | 2020.12.03 |
---|---|
UINavigationController를 사용하여 UIPageViewController에서 푸시 다운 된 콘텐츠 (0) | 2020.12.03 |
모든 자식 요소 가져 오기 (0) | 2020.12.03 |
메소드를 array_map 함수로 사용할 수 있습니까? (0) | 2020.12.02 |
Android에서 일반 Java Array 또는 ArrayList를 Json Array로 변환 (0) | 2020.12.02 |