Estoy usando Retrofit 2 para obtener json y analizarlo para POJO. Mi objetivo es obtener un valor de ese objeto.

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

Mi cliente REST:

public interface MyClient {

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

}

Aquí He encontrado una gran gran herramienta para crear servicio:

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);
    }
}

A continuación, voy a crear nuevo servicio mediante el Servicio de generador de clase:

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();
        }

Cuando estoy tratando de ejecutar este código que estoy recibiendo este error:

android.os.NetworkOnMainThreadException
en android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
en java.net.InetAddress.lookupHostByName(InetAddress.java:418)
en java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
en java.net.InetAddress.getAllByName(InetAddress.java:215)
en okhttp3.Dns$1.búsqueda de Dns.java:39)
en okhttp3.interna.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:173)
en okhttp3.interna.http.RouteSelector.nextProxy(RouteSelector.java:139)
en okhttp3.interna.http.RouteSelector.siguiente(RouteSelector.java:81)
en okhttp3.interna.http.StreamAllocation.findConnection(StreamAllocation.java:174)
en okhttp3.interna.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:127)
en okhttp3.interna.http.StreamAllocation.newStream(StreamAllocation.java:97)
en okhttp3.interna.http.HttpEngine.conectar(HttpEngine.java:289)
en okhttp3.interna.http.HttpEngine.sendRequest(HttpEngine.java:241)
en okhttp3.RealCall.getResponse(RealCall.java:240)
en okhttp3.RealCall$ApplicationInterceptorChain.proceder(RealCall.java:198)
en okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
en okhttp3.RealCall.ejecutar(RealCall.java:57)
en retrofit2.OkHttpCall.ejecutar(OkHttpCall.java:177)
en retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.ejecutar(ExecutorCallAdapterFactory.java:87)
en la uz.cp.ox.de datos.MyRepository.getMyItem(MyRepository.java:31)
en la uz.cp.ox.los presentadores.MyPresenter.hacer(MyPresenter.java:30)
en la uz.cp.ox.actividades.MyActivity.onClick(MyActivity.java:52)
en android.vista.Vista.performClick(Ver.java:4756)
en android.vista.Ver$PerformClick.ejecutar(Ver.java:19749)
en android.os.Controlador.handleCallback(Controlador.java:739)
en android.os.Controlador.dispatchMessage(Controlador.java:95)
en android.os.Looper.loop(Bucle.java:135)
en android.app.ActivityThread.principal(ActivityThread.java:5221)
en java.lang.reflejar.Método.invoke(Native Method)
en java.lang.reflejar.Método.invoke(Método.java:372)
en com.android.interna.os.ZygoteInit$MethodAndArgsCaller.ejecutar(ZygoteInit.java:899)
en com.android.interna.os.ZygoteInit.principal(ZygoteInit.java:694)

Pensé que Retrofit automáticamente hace el trabajo en el subproceso en segundo plano. O no he entendido algo. Lo que está mal en esta situación y cómo resolverlo?

Por favor marque la respuesta y que me haga saber si usted tiene alguna preocupación

OriginalEl autor Joe Richard | 2016-02-18

3 Comentarios

  1. 33

    Pensé que Retrofit automáticamente hace el trabajo en el fondo
    subproceso.

    Si utiliza la versión asíncrona – enqueue. Estás usando la versión sincrónica, que se ejecuta en el hilo de la llamada.

    Llamarlo de esta manera en lugar:

    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
        }
    });

    En onResponse(), utilice response.body() para obtener su respuesta, tales como:

    MyItem myItem=response.body();

    Edit: Solucionado onResponse() & onFailure (a) las firmas y agregó ejemplo a onRespnose().

    Lo que si quiero es llamar al servicio de forma sincrónica?
    Ver este código, a partir de la OP: Call<MyItem> call = api.getMyItem(param1, param2, param3); call.execute().body(); Uso .execute() en lugar de .enqueue.
    Ok, pero cuando lo hacemos llegar NetworkOnMainThreadException, no podemos hacer la sincronización. llamar sin tener excepción?
    Sí @GokhanArik, pero llamarlo de forma sincrónica, usted necesita estar en un subproceso en segundo plano, como en un AsyncTask, un trabajo de la cola o de su propio subproceso en segundo plano.

    OriginalEl autor NightSkyDev

  2. 2

    Está llamando webservice en el hilo principal, que es la razón por la u tiene este error ‘android.os.NetworkOnMainThreadException‘.

    Puede utilizar la anterior codificación contestada por NightSkyDev para obtener los datos de lo que quieres u.

    En Rxjava & Retrofit me olvidé de escribir hilos .subscribeOn(Programadores.io()) .observeOn(AppSchedulers.mainThread()) Así que me sale este error. Gracias por la respuesta

    OriginalEl autor Sai Soe Harn

  3. 2

    En la Retroadaptación de los Dos Tipos de Método de ejecución se lleve a cabo la
    Enqueue – Funciona en segundo plano hilo de manejar automáticamente por retrofit.
    Ejecutar – Obras en el subproceso de interfaz de usuario de forma manual necesaria para poner en el fondo de la rosca o de tomar la ayuda de async tarea.

    OriginalEl autor Rahul Jain

Dejar respuesta

Please enter your comment!
Please enter your name here