Alexei
Alexei

Reputation: 15726

Android, Glide 4.3.0: If you must do so, consider posting your into() or clear() calls to the main thread using a Handler instead

Android Studio 3.2, Glide 4.3.0

I need to custom handle situation when image is not load (e.g. when url is not correct or server doesn't response).

Here my code Fragment:

  public static void loadImage(ImageView view, String imageUrl, GlideRoundedCornersTransformation.CornerType cornerType) {
    RequestOptions requestOptionsTransform = RequestOptions.bitmapTransform(
            new GlideRoundedCornersTransformation(view.getContext(), (int) AndroidUtil.dpToPx(view.getContext(),
                    view.getContext().getResources().getInteger(R.integer.image_rounded_corner_radius_dp)),
                    0, cornerType));
    Glide.with(view.getContext())
            .load(imageUrl)
            .listener(new RequestListener<Drawable>() {
                @Override
                public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                    Glide.with(view.getContext()).load(R.drawable.default_image)
                            .apply(requestOptionsTransform)
                            .into(view));
                    return false;
                }

                @Override
                public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                    view.setImageDrawable(resource);
                    return true;
                }
            })
            .apply(requestOptionsTransform)
            .into(view);
}

But I get this error:

FATAL EXCEPTION: main
Process: com.myproject.android.customer.debug, PID: 25205
java.lang.IllegalStateException: You can't start or clear loads in RequestListener or Target callbacks. If you must do so, consider posting your into() or clear() calls to the main thread using a Handler instead.
    at com.bumptech.glide.request.SingleRequest.assertNotCallingCallbacks(SingleRequest.java:279)
    at com.bumptech.glide.request.SingleRequest.clear(SingleRequest.java:296)
    at com.bumptech.glide.manager.RequestTracker.clearRemoveAndRecycle(RequestTracker.java:62)
    at com.bumptech.glide.RequestManager.untrack(RequestManager.java:443)
    at com.bumptech.glide.RequestManager.untrackOrDelegate(RequestManager.java:430)
    at com.bumptech.glide.RequestManager.clear(RequestManager.java:418)
    at com.bumptech.glide.RequestBuilder.into(RequestBuilder.java:380)
    at com.bumptech.glide.RequestBuilder.into(RequestBuilder.java:432)
    at com.myproject.android.customer.util.CommonUtil$1.onLoadFailed(CommonUtil.java:69)
    at com.bumptech.glide.request.SingleRequest.onLoadFailed(SingleRequest.java:592)
    at com.bumptech.glide.request.SingleRequest.onLoadFailed(SingleRequest.java:572)
    at com.bumptech.glide.load.engine.EngineJob.handleExceptionOnMainThread(EngineJob.java:259)
    at com.bumptech.glide.load.engine.EngineJob$MainThreadCallback.handleMessage(EngineJob.java:291)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:166)
    at android.app.ActivityThread.main(ActivityThread.java:7377)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:469)

Upvotes: 0

Views: 3317

Answers (4)

Maddy_Rockstar
Maddy_Rockstar

Reputation: 39

Follow the suggestion in the exception message and post a Runnable to the main thread that starts your request:

Handler handler = new Handler();
...
@Override
public boolean onLoadFailed(@android.support.annotation.Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
  handler.post(new Runnable() {
    @Override
    public void run() {
      Glide.with(...)
    }
  }
};

Instead of a handler, you can also post a runnable using

view.post(new Runnable() {
....
 })

Upvotes: 1

mortr
mortr

Reputation: 11

You can use Handler.post or targetView.post(Runnable)

......
                    .listener(new RequestListener < Drawable >() {
                        @Override
                        public boolean onLoadFailed(
                            @Nullable GlideException e,
                            Object model,
                            Target<Drawable> target,
                            boolean isFirstResource
                        ) {
                            view.post(new Runnable () {
                                @Override
                                public void run() {
                                    Glide.with(view.getContext()).load(R.drawable.default_image)
                                        .apply(requestOptionsTransform)
                                        .into(view));
                                }
                            })
    
                            return false;
                        }
            .......

Upvotes: 1

Alexei
Alexei

Reputation: 15726

I found solution. Use Glide 4.3.

And here code:

 public static void loadImage(ImageView view, String imageUrl, GlideRoundedCornersTransformation.CornerType cornerType) {
        RequestOptions requestOptionsTransform = RequestOptions.bitmapTransform(
                new GlideRoundedCornersTransformation(view.getContext(), (int) AndroidUtil.dpToPx(view.getContext(),
                        view.getContext().getResources().getInteger(R.integer.image_rounded_corner_radius_dp)),
                        0, cornerType));
        Glide.with(view.getContext())
                .load(imageUrl)
                .error(Glide.with(view.getContext())
                        .load(R.drawable.default_image))
                .apply(requestOptionsTransform)
                .into(view);
    }

I get help from this https://bumptech.github.io/glide/doc/debugging.html#you-cant-start-or-clear-loads-in-requestlistener-or-target-callbacks

Upvotes: 2

Mayur Gajra
Mayur Gajra

Reputation: 9083

You can achieve same thing using applyDefaultRequestOptions and pass RequestOptions.errorOf with your default image if any error occurs. In your case you can do something like:

public static void loadImage2(ImageView view, String imageUrl) {
        Glide.with(view.getContext())
                .applyDefaultRequestOptions(RequestOptions.errorOf(R.drawable.default_image))
                .load(imageUrl)
                .into(view);
    }

For more info on Requestoptions follow this link:

http://bumptech.github.io/glide/doc/options.html

Upvotes: 0

Related Questions