okhttp3 throws NetworkOnMainThreadException when loading images asynchronously with glide Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of okhttp3 throws NetworkOnMainThreadException when loading images asynchronously with glide without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I’m trying to load images asynchronously into a CardPresenter in Leanback like this.

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

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

Unfortunately this doesn’t work as expected. Only a few images are loaded correctly into the card presenter, but most of them are not, and the following error is thrown:

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

It’s totally random which work and which don’t.

I also tried setting the strict mode in MainActivity.java.

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

While this solution loads all images correctly and doesn’t throw any NetworkOnMainThreadException errors, it comes with huge performance issues. The scrolling becomes slow and laggy, showing me the following message:

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

Is there any solution to make the images load asynchronously while still maintaining a smooth and good performance?

Answer

My approach was totally wrong. I thought that BaseGlideUrlLoader runs on a background-thread, but it doesn’t.

So the code to go is the following:

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


}
We are here to answer your question about okhttp3 throws NetworkOnMainThreadException when loading images asynchronously with glide - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji