Glide:加载图像以推送通知
Glide: load image to push notifications
我正在尝试使用 Glide 将图像加载到推送通知,但它是这样说的:
FATAL EXCEPTION: Thread-9730
Process: com.monkingme.monkingmeapp, PID: 24226
java.lang.IllegalArgumentException: You must call this method on the main thread at com.bumptech.glide.util.Util.assertMainThread(Util.java:135)
以及使用的代码:
NotificationTarget notificationTarget = new NotificationTarget(
context,
rv,
R.id.remoteview_notification_icon,
notification,
NOTIFICATION_ID);
Glide.with(context.getApplicationContext())
.load(item.getString("cover_img"))
.asBitmap()
.placeholder(placeholder)
.error(placeholder)
.into(notificationTarget);
我正在使用 Aerogear 的 MessageHandler --> https://aerogear.org/docs/guides/aerogear-android/push/
问题是,在推送通知中,应用不是 运行,因此没有主线程。有什么建议吗?
试试看:
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Glide.with(context.getApplicationContext())
.load(item.getString("cover_img"))
.asBitmap()
.placeholder(placeholder)
.error(placeholder)
.into(notificationTarget);
}
});
我的解决方案:
public class NotificationBuilder {
public static void build(Context context) {
...
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.app_icon_notification).setContentTitle("Title")
.setContentText("Description").setAutoCancel(true).setShowWhen(true)
.setWhen(1574521462).setLights(ledColor, 200, 2000)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setStyle(new NotificationCompat.BigTextStyle().bigText("Description"))
.setTicker("Description").setSound(defaultSoundUri).setContentIntent(pendingIntent);
FutureTarget<Bitmap> futureTarget = GlideApp.with(context).asBitmap()
.load("http://example.com/myImage.jpg")
.circleCrop().submit();
LoadImageTask task = new LoadImageTask(icon -> {
notificationBuilder.setLargeIcon(icon);
GlideApp.with(context).clear(futureTarget);
notificationManager.notify(NotificationsCons.SUPPORT_MESSAGES_NOTIFICATION_ID,
notificationBuilder.build());
});
task.execute(futureTarget);
}
}
private static class LoadImageTask extends AsyncTask<FutureTarget<Bitmap>, Void, Bitmap> {
private OnSuccess onSuccess;
interface OnSuccess {
void onSuccess(Bitmap bitmap);
}
LoadImageTask(OnSuccess onSuccess) {
this.onSuccess = onSuccess;
}
@SafeVarargs @Override
protected final Bitmap doInBackground(FutureTarget<Bitmap>... futureTargets) {
try {
return futureTargets[0].get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if (bitmap != null)
onSuccess.onSuccess(bitmap);
}
}
它工作正常。
对于那些可能对最新版本的 Glide 和 Kotlin 感到困惑的人:
val target = NotificationTarget(
context,
R.id.iv_image,
remoteView,
notification,
NOTIFICATION_ID)
Glide.with(context.applicationContext)
.asBitmap()
.load(url)
.into(target)
请务必注意 asBitmap()
应该紧跟在 with(context)
之后
这是意料之中的。由于图像是从互联网加载的,因此它应该始终在 async 调用或后台线程中。您可以使用异步任务或图像加载库,例如 Glide。
要从 url 加载图像通知,您可以使用样式 "NotificationCompat.BigPictureStyle()"。这需要一个位图(必须从图像url中提取)
大多数 API 和 Glide 的方法现已弃用。
下面是使用 Glide 4.9 和高达 Android 10.
// Load bitmap from image url on background thread and display image notification
private void getBitmapAsyncAndDoWork(String imageUrl) {
final Bitmap[] bitmap = {null};
Glide.with(getApplicationContext())
.asBitmap()
.load(imageUrl)
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
bitmap[0] = resource;
// TODO Do some work: pass this bitmap
displayImageNotification(bitmap[0]);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}
显示一次图像通知,位图准备就绪。
private void displayImageNotification(Bitmap bitmap) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), getChannelId());
builder
.setContentTitle(title)
.setContentText(subtext)
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE)
.setSmallIcon(SMALL_ICON)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setColor(getApplicationContext().getColor(color))
.setAutoCancel(true)
.setOngoing(false)
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent)
.setStyle(
new NotificationCompat.BigPictureStyle().bigPicture(bitmap))
.setPriority(Notification.PRIORITY_HIGH);
getManager().notify(tag, id, builder.build());
}
我正在尝试使用 Glide 将图像加载到推送通知,但它是这样说的:
FATAL EXCEPTION: Thread-9730
Process: com.monkingme.monkingmeapp, PID: 24226
java.lang.IllegalArgumentException: You must call this method on the main thread at com.bumptech.glide.util.Util.assertMainThread(Util.java:135)
以及使用的代码:
NotificationTarget notificationTarget = new NotificationTarget(
context,
rv,
R.id.remoteview_notification_icon,
notification,
NOTIFICATION_ID);
Glide.with(context.getApplicationContext())
.load(item.getString("cover_img"))
.asBitmap()
.placeholder(placeholder)
.error(placeholder)
.into(notificationTarget);
我正在使用 Aerogear 的 MessageHandler --> https://aerogear.org/docs/guides/aerogear-android/push/
问题是,在推送通知中,应用不是 运行,因此没有主线程。有什么建议吗?
试试看:
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Glide.with(context.getApplicationContext())
.load(item.getString("cover_img"))
.asBitmap()
.placeholder(placeholder)
.error(placeholder)
.into(notificationTarget);
}
});
我的解决方案:
public class NotificationBuilder {
public static void build(Context context) {
...
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.app_icon_notification).setContentTitle("Title")
.setContentText("Description").setAutoCancel(true).setShowWhen(true)
.setWhen(1574521462).setLights(ledColor, 200, 2000)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setStyle(new NotificationCompat.BigTextStyle().bigText("Description"))
.setTicker("Description").setSound(defaultSoundUri).setContentIntent(pendingIntent);
FutureTarget<Bitmap> futureTarget = GlideApp.with(context).asBitmap()
.load("http://example.com/myImage.jpg")
.circleCrop().submit();
LoadImageTask task = new LoadImageTask(icon -> {
notificationBuilder.setLargeIcon(icon);
GlideApp.with(context).clear(futureTarget);
notificationManager.notify(NotificationsCons.SUPPORT_MESSAGES_NOTIFICATION_ID,
notificationBuilder.build());
});
task.execute(futureTarget);
}
}
private static class LoadImageTask extends AsyncTask<FutureTarget<Bitmap>, Void, Bitmap> {
private OnSuccess onSuccess;
interface OnSuccess {
void onSuccess(Bitmap bitmap);
}
LoadImageTask(OnSuccess onSuccess) {
this.onSuccess = onSuccess;
}
@SafeVarargs @Override
protected final Bitmap doInBackground(FutureTarget<Bitmap>... futureTargets) {
try {
return futureTargets[0].get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if (bitmap != null)
onSuccess.onSuccess(bitmap);
}
}
它工作正常。
对于那些可能对最新版本的 Glide 和 Kotlin 感到困惑的人:
val target = NotificationTarget(
context,
R.id.iv_image,
remoteView,
notification,
NOTIFICATION_ID)
Glide.with(context.applicationContext)
.asBitmap()
.load(url)
.into(target)
请务必注意 asBitmap()
应该紧跟在 with(context)
这是意料之中的。由于图像是从互联网加载的,因此它应该始终在 async 调用或后台线程中。您可以使用异步任务或图像加载库,例如 Glide。
要从 url 加载图像通知,您可以使用样式 "NotificationCompat.BigPictureStyle()"。这需要一个位图(必须从图像url中提取)
大多数 API 和 Glide 的方法现已弃用。 下面是使用 Glide 4.9 和高达 Android 10.
// Load bitmap from image url on background thread and display image notification
private void getBitmapAsyncAndDoWork(String imageUrl) {
final Bitmap[] bitmap = {null};
Glide.with(getApplicationContext())
.asBitmap()
.load(imageUrl)
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
bitmap[0] = resource;
// TODO Do some work: pass this bitmap
displayImageNotification(bitmap[0]);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}
显示一次图像通知,位图准备就绪。
private void displayImageNotification(Bitmap bitmap) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), getChannelId());
builder
.setContentTitle(title)
.setContentText(subtext)
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE)
.setSmallIcon(SMALL_ICON)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setColor(getApplicationContext().getColor(color))
.setAutoCancel(true)
.setOngoing(false)
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent)
.setStyle(
new NotificationCompat.BigPictureStyle().bigPicture(bitmap))
.setPriority(Notification.PRIORITY_HIGH);
getManager().notify(tag, id, builder.build());
}