java - 改造 - android.os.NetworkOnMainThreadException

标签 java android retrofit retrofit2

我正在使用 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);

}

Here我发现了创建服务的绝佳工具:

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

然后我使用服务生成器类创建新服务:

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

我认为 Retrofit 会自动在后台线程中完成这项工作。或者我误解了什么。这种情况出了什么问题,如何解决?

最佳答案

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

如果您使用异步版本 - 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() 添加了示例。

关于java - 改造 - android.os.NetworkOnMainThreadException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35481990/

相关文章:

java - 尝试使用 Twitter4J 在 java 中发布推文

java - 我无法更改 android studio 中的 Activity 主题

java - 如何获取列表的下三个元素

android - 动态显示来自资源/可绘制的图像

android - android webview 中的 onClick 事件太慢

android - OkHttp + 改造离线缓存不起作用

java - RxJava retryWhen 重新订阅传播

java - 井字游戏问题

java - 以编程方式向 ShapeDrawable 添加阴影

java - 如何使用改造获取其中的数据