In order to speed up things, I would like to check the Glide cache on a specific Image URL first and do the asynchronous query only if the bitmap is not in the cache. Something like this (glideCache and getOnlyIfinCache is what I am looking for) :
bitmap=null;
bitmap = glideCache.getOnlyIfinCache(ImageURL);
if (bitmap!=null) { // the bitmap is available
createNotif(bitmap);
nmc.notify(notificationId, notification);
} else { // the bitmap is not available. Need to get it on internet
Glide
.with(context.getApplicationContext())
.load(imageUrl)
.asBitmap()
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap largeIcon, GlideAnimation glideAnimation) {
createNotif(largeIcon);
nmc.notify(notificationId, notification);
}
});
}
There's a class for handling notifications, but that won't help with your cache query.
I think what you want is just the default behavior of Glide. If the image is in memory cache the onResourceReady will be called synchronously, if it's in the disk cache there's no point in loading it synchronously (I/O on UI thread), so onResourceReady will be called a little later after the Bitmap has been decoded from the SDCard File (the same amount of time that would take if you were doing it on the UI thread, but without blocking the UI events). If none of these happen then Glide goes to the network, so just the Glide... statement you have should cover all cases without any ifs or cache queries.
I did not know that onResourceReady is called synchronously when the bitmap is in the memory cache.
So if I understand you well, you are suggesting to just do a :
Glide
.with(context.getApplicationContext())
.load(imageUrl)
.asBitmap()
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap largeIcon, GlideAnimation glideAnimation) {
createNotif(largeIcon);
nmc.notify(notificationId, notification);
}
});
each time I want to update my notification (even if I update other paramaters than the bitmap)?
PS : NotificationTarget class works only if you use RemoteViews, which is not what I use. I set up the notification with the new MediaStyle. So I have no choice but to extend SimpleTarget.
Ah I think I see what's your problem. You can just save the largeIcon Bitmap into a field of your model and use that Bitmap when you're updating the text (you can do this because you're using application context to load). Something like below.
(I've never displayed a notification either way so take the code with a grain of salt.)
class Notif {
private String message;
private Bitmap icon;
private NotificationManager nmc;
private int id;
private Notification notification;
private Context context;
private Target<Bitmap> target = new SimpleTarget<Bitmap>() {
@Override public void onLoadCleared(Drawable placeholder) {
icon = null;
update();
}
@Override public void onResourceReady(Bitmap largeIcon, GlideAnimation glideAnimation) {
icon = largeIcon;
update();
}
};
Notif(Context context, ...) {
// initialize id, context, notification, etc.
}
void update() {
createNotif(icon);
nmc.notify(id, notification);
}
void setIcon(String imageUrl) {
Glide.clear(target); // free previous icon
Glide
.with(context.getApplicationContext())
.load(imageUrl)
.asBitmap()
.into(target);
}
void setMessage(String message) {
this.message = message;
update();
}
void onDismissed() {
Glide.clear(target); // let the bitmap go
}
}
Ok. Thanks Rob. I will see how I can use this. As the notification manager can receive lots of different image URsL ,I will have to create a Map
I meant this Notif class to represent a single notification with changing data. You don't need a map just a list of these objects. Again, your "map" is hidden in the memory cache. Just request an Uri and it'll be returned to you (the fastest possible). I'm curious what you end up doing (even if just a few sentences) please report back!
Thanks for you help but I am realizing it's lots of work to just possibly gain a few milliseconds at each notification update.
For the time being, each time I want to update the parameter of the notification i send a:
Glide
.with(context.getApplicationContext())
.load(imageUrl)
.asBitmap()
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap largeIcon, GlideAnimation glideAnimation) {
buildNotification(largeIcon);
nmc.notify(notificationId, notification);
}
});
you kind of convince me it might be the best solution.
PS. If you are a Glide designer I suggest the following feature: create a MediaStyleNotificationTarget class similar to NotificationTarget which is used for notification built with RemoteViews.
A MediaStyle is a new style for media notification that can be built like that:
void buildNotification(Bitmap largeIcon) {
notificationBuilder = new NotificationCompat.Builder(act)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setCategory(NotificationCompat.CATEGORY_TRANSPORT)
.setContentTitle(podcastName)
.setContentText(episodeName)
.setOngoing(true)
.setShowWhen(false)
.setContentIntent(activityMainPI)
.setSmallIcon(smallIcon)
.setLargeIcon(largeIcon)
.setAutoCancel(false)
.addAction(previousAction)
.addAction(playAction)
.addAction(nextAction)
.addAction(rewindAction)
.addAction(forwardAction)
.setStyle(new MediaStyle()
// .setMediaSession(mediaSession.getSessionToken())
.setShowActionsInCompactView(new int[]{1})
);
notification = notificationBuilder.build();
}
Thanks for the update.
Feel free to create a PR if you feel like it would be a good addition.
That's how the other target was added too: #242/#248.
@u2gilles hi, did you find a solution for the MediaStyle notification class working with Glide? I am in the exact situation and my Google searches led me here.
@TWiStErRob just from the code, I realize using SimpleTarget, the app will have to wait till the image is loaded oResourceReady to fire a notification, wouldn't it a bad experience for a user especially in a music application, when they press next/previous buttons and I need to update the notification immediately? Could it be possible to show the notification as it waits for the image to load like for the case of listviews? Your help will be highly appreciated....
@jaymoh I think in your case I would have a thumbnail or very small image that loads instantly then once the larger image is loaded, updated the notification by ID. ...or you may be able to just update the remoteView, have not tested how that would redraw.
I can still fire a PR for MediaStyle notification Target?
Most helpful comment
Ah I think I see what's your problem. You can just save the
largeIconBitmap into a field of your model and use that Bitmap when you're updating the text (you can do this because you're using application context to load). Something like below.(I've never displayed a notification either way so take the code with a grain of salt.)