Glide assert: java.lang.IllegalArgumentException: You must call this method on the main thread

Glide assert: java.lang.IllegalArgumentException: You must call this method on the main thread

有没有人用过 Glide 从后台线程中获取图像?我不断收到这个断言:

java.lang.IllegalArgumentException: You must call this method on the main thread

但是根据这个线程,它应该可以工作:

https://github.com/bumptech/glide/issues/310

但是,我无法让它工作,除非我从主线程调用它。

这是我在主线程中尝试做的事情:

    Glide.get(mContext);
    loadUserImage(userImageUrl);

    // wait 5 seconds before trying again
    int imageLoadingTimeOut = mContext.getResources().getInteger(R.integer.image_loading_time_out);
    if (imageLoadingTimeOut > 0) {
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                if (!mUserImageLoaded) {
                    loadUserImage(userImageUrl);
                }
            }
        }, imageLoadingTimeOut);
    }
}

和加载用户图像:

private boolean mUserImageLoaded = false;

private void loadUserImage(String userImageUrl) {

    if (userImageUrl != null && !userImageUrl.isEmpty() && !mUserImageLoaded) {
        Glide.with(mContext).using(Cloudinary.getUrlLoader(mContext)).load(userImageUrl).crossFade().listener(new RequestListener<String, GlideDrawable>() {

            @Override
            public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
                return false;
            }

            @Override
            public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                mImageMessageContent.invalidate();
                mUserImageLoaded = true;
                return false;
            }
        }).into(mImageMessageContent);

    } else {
        mImageMessageContent.setVisibility(View.GONE);
    }
}

而 mContext 只是 activity "this" 指针。

无论如何,我可以从不同于主线程的线程使用 Glide 吗?

Glideinto(ImageView) 方法要求您仅在主线程上调用它,但是当您将加载传递给 Timer 时,它将在 background 线程中执行。

你可以做的是通过调用 get() 而不是 into() 来检索位图,然后通过调用 [=18= 在 ImageView 上设置 bitmap ].

Glide.with(getApplicationContext())
     .load("your url")
     .asBitmap()
     .into(new BitmapImageViewTarget(imgView) {
      @Override
      protected void setResource(Bitmap resource) {
       //Play with bitmap
        super.setResource(resource);
      }
    });

您也可以查看此 document 了解更多信息。

发布代码以防对某人有帮助。

Bitmap myBitmap = Glide.with(applicationContext)
        .load(yourUrl)
        .asBitmap()
        .centerCrop()
        .into(Target.SIZE_ORIGINAL,Target.SIZE_ORIGINAL)
        .get()
imageView.setImageBitmap(myBitmap);

Update image in main ui thread

runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Glide.with(MainActivity.this)
                                    .load("image URL")
                                    .into(imageView);
                        }
                    });

在我的例子中,我想显示来自 FirebaseMessagingService 的通知以及将通过 Glide 下载的图像,让我成功的是这段代码:

try {
                    Bitmap bitmap= Glide.with(getApplicationContext())
                            .load(imageUrl)   // image url in string
                            .asBitmap().into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get();

                    // now i can pass bitmap to notificationBuilder like
                 notificationBuilder.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(bitmap)); 

                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
 private class AsyncTaskRunner extends AsyncTask<String, String, RequestBuilder>
{
    ProgressDialog progressDialog;
    @Override
    protected void onPreExecute() {
        progressDialog = ProgressDialog.show(MainActivity.this,
                "Please Wait",
                "Image is loading...");
    }

    @Override
    protected RequestBuilder<Drawable> doInBackground(String... strings) {
        URL url = null;
        try {
            url = new URL(strings[0]);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        RequestBuilder<Drawable> g= Glide.with(MainActivity.this).load(url);
        return g;
    }

    @Override
    protected void onPostExecute(RequestBuilder v) {
        v.into(imageView);
        imageView.setVisibility(View.VISIBLE);
        progressDialog.dismiss();
    }
}

这是 Kotlin 方式的解决方案

Glide.with(context).asBitmap().load(photo_url).into(
      BitmapImageViewTarget(imgYourResourceID)
)

我需要在 recyclerView 中解密和显示大图像 而且因为这是一个繁重的过程,我不得不在后台进行,所以这就是为什么:

 public void decryptImage(Uri uri, ViewHolder holder) {

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {

                Glide.with(G.context)
                        .asBitmap()
                        .load(decrypt(G.getEncryptionKey(), G.getConstantKey(), uri.getPath()))
                        .into(new SimpleTarget<Bitmap>() {
                            @Override
                            public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
                                Glide.with(G.context).load(resource).into(holder.mImageView);
                            }

                        });
    
        }
    };
    new Thread(runnable).start();


}