当使用glide异步加载图像时,okhttp3抛出NetworkOnMainThreadException

问题描述 投票:0回答:1

我正试图像这样异步地将图像加载到Leanback中的CardPresenter中。

public interface CustomImageModel {  
    String requestCustomUrl(int width, int height);
}

public static class CustomImageModelGrabber implements CustomImageModel {

    public CustomImageModelGrabber() {

    }

    @Override
    public String requestCustomUrl(int width, int height) {
        OkHttpClient client = new OkHttpClient;
        Request request = new Request.Builder().url(image_url).build();
        return client.newCall(request).execute().body().string();
    }
}

public static class CustomImageUrlLoader extends BaseGlideUrlLoader<CustomImageModel> {  
    public CustomImageUrlLoader(Context context) {
        super( context );
    }

    @Override
    protected String getUrl(CustomImageModel model, int width, int height) {
        return model.requestCustomUrl();
    }
}

在CardPresenter.java中

@Override
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {

    CustomImageModel customImageRequest = new CustomImageModelGrabber();

    Glide  
            .with( context )
            .using( new CustomImageUrlLoader( context ) )
            .load( customImageRequest )
            .into( imageView1 );
}

不幸的是,这不能按预期工作。只有少数图像正确加载到卡片展示器中,但大部分图像都没有加载,并引发以下错误:

android.os.NetworkOnMainThreadException
android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)

这是完全随机的工作,而不是。

我也尝试在MainActivity.java中设置严格模式。

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

虽然此解决方案正确加载所有图像并且不会抛出任何NetworkOnMainThreadException错误,但它会带来巨大的性能问题。滚动变得缓慢且滞后,向我显示以下消息:

I/Choreographer: Skipped 182 frames!  The application may be doing too much work on its main thread.

是否有任何解决方案可以使图像异步加载,同时仍保持平滑和良好的性能?

android asynchronous android-glide okhttp3 leanback
1个回答
0
投票

我的方法完全错了。我认为BaseGlideUrlLoader运行在后台线程上,但事实并非如此。

所以要执行的代码如下:

@Override
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {

    final ImageCardView cardView = (ImageCardView) viewHolder.view;

    OkHttpClient client = new OkHttpClient;
    Request request = new Request.Builder().url(image_url).build();


    client.newCall(request).enqueue(new Callback() {
      @Override public void onFailure(Call call, IOException e) {
        e.printStackTrace();
      }

      @Override public void onResponse(Call call, Response response) throws IOException {
        try (ResponseBody responseBody = response.body()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);


            String imageFromResponse = responseBody.string();
            // do whatever is needed to get the image (i.e JSON-handling)

            Handler mainHandler = new Handler(Looper.getMainLooper());
            Runnable myRunnable = new Runnable() {
                @Override
                public void run() {
                    Glide.with(cardView.getContext())
                            .load(imagefromResponse)
                            .error(mDefaultCardImage)
                            .into(cardView.getMainImageView());
                }
            };
        }
    });


}
© www.soinside.com 2019 - 2024. All rights reserved.