Skip to content

Target.onBitmapLoaded() method not called sometimes #1537

Closed
@zelongg

Description

@zelongg

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

tpfaff commented on Dec 7, 2016

@tpfaff

Keep a reference to your Target, your invocation with new Target(){...} is getting GCd.

JakeWharton

JakeWharton commented on Jan 5, 2017

@JakeWharton
Collaborator

The best you can do is keep a Set/Map or return the Target instance to the caller.

ghost

ghost commented on Jan 7, 2017

@ghost

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

gongzelong0718 commented on Apr 26, 2018

@gongzelong0718

Marked

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @JakeWharton@tpfaff@gongzelong0718@zelongg

        Issue actions

          Target.onBitmapLoaded() method not called sometimes · Issue #1537 · square/picasso