Closed
Description
it is similar with #669
But the issue is closed.
@JakeWharton
I know it may be silly.
How to store it on a field in a view holder or implement it on a subclass of a view or the like?
Here is my scenario.
I need to download an icon to show in the notification.
I paste the related code which might be a bit too long. But it may do good to making it clear.
fetchIconAndShow(context, iconUrl, new Callback<Bitmap>() {
@Override
public void run(Bitmap bitmap) {
OpLog.d("gongzelong", "run notify");
NewsNotificationHandler.notify(context, article, bitmap, contentIntent);
}
});
}
private static void fetchIconAndShow(Context context, @Nullable String iconUrl,
final Callback<Bitmap> callback) {
if (TextUtils.isEmpty(iconUrl)) {
// Display with the default icon.
OpLog.d("gongzelong", "iconUrl isEmpty");
callback.run(null);
} else {
// Load icon first.
NetworkManager.getPicasso()
.load(iconUrl)
.memoryPolicy(MemoryPolicy.NO_CACHE)
.networkPolicy(NetworkPolicy.NO_CACHE)
.into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
OpLog.d("gongzelong", "onBitmapLoaded");
callback.run(bitmap);
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
OpLog.d("gongzelong", "onPrepareLoad");
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
OpLog.d("gongzelong", "onBitmapFailed");
callback.run(null);
}
});
}
}
private static void notify(Context context, Bundle extras, @Nullable Bitmap icon) {
// Send back to the appboy receiver and handle the subsequent opened
// action(APPBOY_NOTIFICATION_OPENED) in AppboyBroadcastReceiver.
Intent pushOpenedIntent = new Intent(
Constants.APPBOY_PUSH_CLICKED_ACTION).setClass(context,
AppboyNotificationUtils.getNotificationReceiverClass());
pushOpenedIntent.putExtras(extras);
PendingIntent pushOpenedPendingIntent =
PendingIntent.getBroadcast(context,
IntentUtils.getRequestCode(), pushOpenedIntent,
PendingIntent.FLAG_ONE_SHOT);
Bundle pushExtras = extras.getBundle(Constants.APPBOY_PUSH_EXTRAS_KEY);
int defaults = 0;
int priority = Notification.PRIORITY_DEFAULT;
int flags = getFlags(pushExtras);
if ((flags & FLAG_SOUND) != 0) {
defaults |= Notification.DEFAULT_SOUND;
}
if ((flags & FLAG_VIBRATE) != 0) {
defaults |= Notification.DEFAULT_VIBRATE;
}
if ((flags & FLAG_LIGHTS) != 0) {
defaults |= Notification.DEFAULT_LIGHTS;
}
if ((flags & FLAG_HEADS_UP) != 0) {
// These below make system UI choose to display a heads-up notification
defaults |= Notification.DEFAULT_VIBRATE;
priority = Notification.PRIORITY_MAX;
}
String notificationId = getNotificationId(pushExtras);
showNotification(context,
pushExtras.getString(TITLE_KEY), pushExtras.getString(TEXT_KEY), icon,
pushOpenedPendingIntent, defaults, priority,
null, notificationId.hashCode());
onOperationEnd(context, notificationId);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static void showNotification(Context context,
String title, @Nullable String text, @Nullable Bitmap icon,
PendingIntent contentIntent, int defaults, int priority,
@Nullable String notificationTag, int notificationId) {
OpLog.d("gongzelong", "showNotification");
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.feed_notification);
if (icon != null) {
remoteViews.setImageViewBitmap(R.id.icon, icon);
} else {
// Fallback to the default icon
remoteViews.setImageViewResource(R.id.icon, R.drawable.icon);
// Also hide the small icon
remoteViews.setViewVisibility(R.id.small_icon, View.GONE);
}
remoteViews.setTextViewText(R.id.title, title);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
builder.setSmallIcon(R.drawable.push_icon)
.setContentIntent(contentIntent)
.setCustomContentView(remoteViews)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setAutoCancel(true)
.setDefaults(defaults)
.setPriority(priority);
NotificationManager notificationMgr = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification n = builder.build();
notificationMgr.notify(notificationTag, notificationId, n);
} else {
builder.setSmallIcon(R.drawable.push_icon)
.setContentIntent(contentIntent)
.setContent(remoteViews)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setAutoCancel(true)
.setDefaults(defaults)
.setPriority(priority);
NotificationManager notificationMgr = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
notificationMgr.notify(notificationTag, notificationId, builder.build());
}
}
Activity
tpfaff commentedon Dec 7, 2016
Keep a reference to your Target, your invocation with new Target(){...} is getting GCd.
JakeWharton commentedon Jan 5, 2017
The best you can do is keep a
Set
/Map
or return theTarget
instance to the caller.ghost commentedon Jan 7, 2017
I have a LinearLayout implementing the Target interface, my LinearLayout reference is kept in the activity and any Target's methods are being called.
gongzelong0718 commentedon Apr 26, 2018
Marked