Подтвердить что ты не робот

Retrofit - android.os.NetworkOnMainThreadException

Я использую Retrofit 2, чтобы получить json и разобрать его на POJO. Моя цель - получить одно значение этого объекта.

compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'

Мой клиент REST:

public interface MyClient {

    @GET("/part1/part2")
    Call<MyItem> getMyItem(@Query("param1") String param1,
                                                 @Query("param2") String param2,
                                                 @Query("param3") String param3);

}

Здесь Я нашел отличный отличный инструмент для создания сервиса:

public class ServiceGenerator {

    public static final String API_BASE_URL = "http://my.api.com";

    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

    private static Retrofit.Builder builder =
            new Retrofit.Builder()
                    .baseUrl(API_BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create());

    public static <S> S createService(Class<S> serviceClass) {
        Retrofit retrofit = builder.client(httpClient.build()).build();
        return retrofit.create(serviceClass);
    }
}

Затем я создаю новый сервис, используя класс Generator Service:

MyClient api = ServiceGenerator.createService(MyClient.class);
        Call<MyItem> call = api.getMyItem(param1, param2, param3);
        MyItem myItem= null;
        try {
            myItem= call.execute().body();
            Log.d("MyTag", myItem.getValue());
        } catch (IOException e) {
            e.printStackTrace();
        }

Когда я пытаюсь запустить этот код, я получаю эту ошибку:

android.os.NetworkOnMainThreadException                                                               на android.os.StrictMode $AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)                                                               в java.net.InetAddress.lookupHostByName(InetAddress.java:418)                                                               в java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)                                                               в java.net.InetAddress.getAllByName(InetAddress.java:215)                                                               at okhttp3.Dns $1.lookup(Dns.java:39)                                                               at okhttp3.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:173)                                                               в okhttp3.internal.http.RouteSelector.nextProxy(RouteSelector.java:139)                                                               at okhttp3.internal.http.RouteSelector.next(RouteSelector.java:81)                                                               at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174)                                                               at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:127)                                                               at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)                                                               на okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:289)                                                               at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:241)                                                               at okhttp3.RealCall.getResponse(RealCall.java:240)                                                               at okhttp3.RealCall $ApplicationInterceptorChain.proceed(RealCall.java:198)                                                               at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)                                                               at okhttp3.RealCall.execute(RealCall.java:57)                                                               в retrofit2.OkHttpCall.execute(OkHttpCall.java:177)                                                               at retrofit2.ExecutorCallAdapterFactory $ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:87)                                                               в uz.cp.ox.data.MyRepository.getMyItem(MyRepository.java:31)                                                               на uz.cp.ox.presenters.MyPresenter.do(MyPresenter.java:30)                                                               at uz.cp.ox.activities.MyActivity.onClick(MyActivity.java:52)                                                               at android.view.View.performClick(View.java:4756)                                                               на android.view.View $PerformClick.run(View.java:19749)                                                               на android.os.Handler.handleCallback(Handler.java:739)                                                               на android.os.Handler.dispatchMessage(Handler.java:95)                                                               на android.os.Looper.loop(Looper.java:135)                                                               at android.app.ActivityThread.main(ActivityThread.java:5221)                                                               в java.lang.reflect.Method.invoke(собственный метод)                                                               в java.lang.reflect.Method.invoke(Method.java:372)                                                               at com.android.internal.os.ZygoteInit $MethodAndArgsCaller.run(ZygoteInit.java:899)                                                               на com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

Я думал, что Retrofit автоматически выполняет задание в фоновом потоке. Или я что-то не понял. Что не так в этой ситуации и как ее решить?

4b9b3361

Ответ 1

Я думал, что Retrofit автоматически выполняет работу в фоновом режиме нить.

Это происходит, если вы используете асинхронную версию - enqueue. Вы используете синхронную версию, которая работает на вызывающем потоке.

Назовите это следующим образом:

MyClient api = ServiceGenerator.createService(MyClient.class);
Call<MyItem> call = api.getMyItem(param1, param2, param3);
call.enqueue(new Callback<MyItem>() {
    @Override
    public void onResponse(Call<MyItem> call, Response<MyItem> response) {
        MyItem myItem=response.body();
    }

    @Override
    public void onFailure(Call<MyItem> call, Throwable t) {
        //Handle failure
    }
});

В onResponse() используйте response.body(), чтобы получить ответ, например:
  MyItem myItem=response.body();

Изменить: исправлены сигнатуры onResponse() и onFailure() и добавлен пример в onRespnose().

Ответ 2

В ретрофитете происходят два типа выполнения метода - Enqueue. Работает в фоновом потоке автоматически с помощью модификации. Выполнять. Работает в потоке пользовательского интерфейса вручную, чтобы добавить либо фоновый поток, либо выполнить справку async.

Ответ 3

Вы вызываете webservice в основном потоке, поэтому u получил эту ошибку ' android.os.NetworkOnMainThreadException.

Вы можете использовать приведенную выше кодировку, на которую отвечает NightSkyDev, чтобы получить данные, которые вы хотите.