J'utilise Retrofit 2 pour obtenir json et l'analyser en POJO. Mon but est d'obtenir une valeur de cet objet.
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
Mon REST:
public interface MyClient {
@GET("/part1/part2")
Call<MyItem> getMyItem(@Query("param1") String param1,
@Query("param2") String param2,
@Query("param3") String param3);
}
Ici J'ai trouvé un excellent outil pour créer un service:
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);
}
}
Ensuite, je crée un nouveau service en utilisant la classe Générateur de services:
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();
}
Lorsque j'essaie d'exécuter ce code, j'obtiens cette erreur:
Android.os.NetworkOnMainThreadException sur Android.os.StrictMode $ AndroidBlockGuardPolicy.onNetwork (StrictMode.Java:1147) sur Java.net.InetAddress.lookupHostByName (InetAddress.Java:418) sur Java.net.InetAddress.getAllByNameImpl (Inet 252) sur Java.net.InetAddress.getAllByName (InetAddress.Java:215) sur okhttp3.Dns $ 1.lookup (Dns.Java:39) sur okhttp3.internal.http.RouteSelector.resetNextInetSocketAddress (RouteSelector.Java:173) sur okhttp3 .internal.http.RouteSelector.nextProxy (RouteSelector.Java:139) sur okhttp3.internal.http.RouteSelector.next (RouteSelector.Java:81) sur okhttp3.internal.http.StreamAllocation.findConnection (StreamAllocation.Java:174) okhttp3.internal.http.StreamAllocation.findHealthyConnection (StreamAllocation.Java:127) à okhttp3.internal.http.StreamAllocation.newStream (StreamAllocation.Java:97) à okhttp3.internal.http.HttpEngine.connect (Http.Http.HttpEngine.connect (Http). à okhttp3.internal.http.HttpEngine.sendRequest (HttpEngine.Java:241) à okhttp3.RealCall.getResponse (RealCall .Java: 240) à okhttp3.RealCall $ ApplicationInterceptorChain.proceed (RealCall.Java:198) à okhttp3.RealCall.getResponseWithInterceptorChain (RealCall.Java:160) à okhttp3.RealCall.execute (RealCall.JttitCOtallOJof:5C) .execute (OkHttpCall.Java:177) à retrofit2.ExecutorCallAdapterFactory $ ExecutorCallbackCall.execute (ExecutorCallAdapterFactory.Java:87) à uz.cp.ox.data.MyRepository.getMyItem (MyRepository.Java.cp.ox). presenters.MyPresenter.do (MyPresenter.Java:30) sur uz.cp.ox.activities.MyActivity.onClick (MyActivity.Java:52) sur Android.view.View.performClick (View.Java:4756) sur Android.view .View $ PerformClick.run (View.Java:19749) sur Android.os.Handler.handleCallback (Handler.Java:739) sur Android.os.Handler.dispatchMessage (Handler.Java:95) sur Android.os.Looper. loop (Looper.Java:135) sur Android.app.ActivityThread.main (ActivityThread.Java:5221) sur Java.lang.reflect.Method.invoke (Native Method) sur Java.lang.reflect.Method.invoke (Method. Java: 372) sur com.Android.internal.os.ZygoteIn it $ MethodAndArgsCaller.run (ZygoteInit.Java:899) sur com.Android.internal.os.ZygoteInit.main (ZygoteInit.Java:694)
Je pensais que Retrofit fait automatiquement le travail dans le thread d'arrière-plan. Ou j'ai mal compris quelque chose. Qu'est-ce qui ne va pas dans cette situation et comment y remédier?
Je pensais que Retrofit fait automatiquement le travail dans le thread d'arrière-plan.
C'est le cas si vous utilisez la version asynchrone - enqueue
. Vous utilisez la version synchrone, qui s'exécute sur le thread appelant.
Appelez-le de cette façon à la place:
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
}
});
Dans onResponse (), utilisez response.body()
pour obtenir votre réponse, par exemple:MyItem myItem=response.body();
Edit: correction des signatures onResponse () onFailure () et ajout d'un exemple à onRespnose ().
Vous appelez webservice sur le thread principal, c'est pourquoi vous avez cette erreur ' Android.os.NetworkOnMainThreadException '.
Vous pouvez utiliser le codage ci-dessus répondu par NightSkyDev pour obtenir les données que vous voulez.
Dans Retrofit, deux types d'exécution de méthode ont lieu - Enqueue - Fonctionne sur le thread d'arrière-plan automatiquement géré par retrofit. Execute - Fonctionne sur le thread d'interface utilisateur manuellement requis pour mettre dans le thread d'arrière-plan ou prendre l'aide de la tâche asynchrone.