2016-02-18 25 views
14

Ben json almak ve POJO için ayrıştırmak için Retrofit 2 kullanıyorum. Amacım bu nesnenin bir değerini elde etmektir.Retrofit - android.os.NetworkOnMainThreadException

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

Benim DİNLENME istemcisi:

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

ben Servis jeneratör sınıfını kullanarak yeni bir hizmet oluşturma:

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(); 
     } 
Ben hizmet oluşturmak için büyük büyük bir araç bulundu

public interface MyClient { 

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

} 

Here

Ben bu hatayı alıyorum bu kodu çalıştırmak çalışıyorum zaman:

android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147) at java.net.InetAddress.lookupHostByName(InetAddress.java:418) at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252) at java.net.InetAddress.getAllByName(InetAddress.java:215) at okhttp3.Dns$1.lookup(Dns.java:39) at okhttp3.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:173) at 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) at 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) at retrofit2.OkHttpCall.execute(OkHttpCall.java:177) at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:87) at uz.cp.ox.data.MyRepository.getMyItem(MyRepository.java:31) at 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) at android.view.View$PerformClick.run(View.java:19749) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5221) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

Ben Retrofitler otomatik arka plan iş parçacığı işi yapar düşündük. Ya da bir şeyi yanlış anladım. Bu durumda yanlış olan nedir ve nasıl çözülür?

+0

Lütfen cevabı kontrol edin ve endişeleriniz olursa lütfen bize bildirin – Rahul

cevap

29

I thought that Retrofit automatically does the job in the background thread.

Eşzamansız sürümü kullanıyorsanız - enqueue. Çağrı iş parçacığı üzerinde çalışan eşzamanlı sürümünü kullanıyorsunuz.

yerine bu şekilde arayın:
MyItem myItem=response.body();

Düzenleme:: örneğin, yanıtınızı almak için response.body() kullanın onResponse yılında

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

() (Sabit onResponse() & onFailure) imzalar ve onRespnose() öğesine örnek ekledik.

+4

Servis senkronize etmek için ne ararsam? – Iqbal

+0

Bu kodu OP'den alın: 'Ara call = api.getMyItem (param1, param2, param3); call.execute(). Body(); ' ' .exquute() 'yerine' .enqueue' kullanın. – NightSkyDev

+2

Tamam, ancak bunu yaptığımızda "NetworkOnMainThreadException" alıyoruz, senkronizasyon yapamıyoruz. istisnasız çağrı? –

1

Web işlecini ana iş parçacığına çağırıyorsunuz, bu yüzden 'android.os.NetworkOnMainThreadException' hatası var.

İstediğiniz verileri almak için NightSkyDev tarafından yanıtlanan yukarıdaki kodlamayı kullanabilirsiniz. Yöntem yürütme İki Tür yer- Kuyruğa alır Retrofit olarak

2

- otomatik güçlendirme tarafından idare arka plan iş parçacığı üzerinde çalışır. Yürüt - Arka plan iş parçacığına yerleştirmek veya eşzamansız görevden yardım almak için UI iş parçacığı üzerinde el ile çalışması gerekir.