Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Target.onBitmapLoaded() method not called the first time #669

Closed
ahmed-hamdy90 opened this issue Sep 25, 2014 · 4 comments
Closed

Target.onBitmapLoaded() method not called the first time #669

ahmed-hamdy90 opened this issue Sep 25, 2014 · 4 comments

Comments

@ahmed-hamdy90
Copy link

I knows that is a bug in Target , I just went to knows how to implementation of Object.equals(Object) and Object.hashCode() like in documentation
my code is :

Picasso.with(ctx).load(company.getCompany().getLogoUrl()).into(new Target(){
                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) {
                    imageLoadered = true;
                    imgLogo.setImageBitmap(bitmap);
                    bitmapOfImage = bitmap;
                    Log.e("App","Success to load company logo in onBitmapLoaded method");
                }

                @Override
                public void onBitmapFailed(Drawable drawable) {
                    imageLoadered = false;
                    imgLogo.setBackgroundResource(R.drawable.black_border);
                    imgLogo.setImageResource(R.drawable.building);
                    Log.e("App","Failed to load company logo in onBitmapFailed method");
                }

                @Override
                public void onPrepareLoad(Drawable drawable) {
                    imgLogo.setImageResource(R.drawable.loading);
                    Log.e("App","Prepare to load company logo in onPrepareLoad method");
                }

                @Override
                public boolean equals(Object o) {
                    Log.e("App","in override equals method");
                    return super.equals(o);
                }

                @Override
                public int hashCode() {
                    Log.e("App","in override hashCode method");
                    return super.hashCode();
                }

            });
@JakeWharton
Copy link
Member

That documentation is misleading. We should remove it.

Your problem is that nothing keeps a strong reference to the Target instance so it gets garbage collected. Either store it in a field or implement it on a View subclass.

@ahmed-hamdy90
Copy link
Author

@JakeWharton I Solve The problem By create a new class implement Target , I cant implement Targetinto myViewBecause give a error: Ambiguous method call Both into(Target) in RequestCreator and into(ImageView) in RequestCreator match`
when use this view with into method.

MySolution :

    private CompanyLogoTarget target = new CompanyLogoTarget();

    Picasso.with(ctx).load(company.getCompany().getLogoUrl()).into(target);

    private class CompanyLogoTarget implements Target {

        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) {
            imageLoadered = true;
            imgLogo.setImageBitmap(bitmap);
            bitmapOfImage = bitmap;
            Log.e("App","Success to load company logo in onBitmapLoaded method");
        }

        @Override
        public void onBitmapFailed(Drawable drawable) {
            imageLoadered = false;
            imgLogo.setBackgroundResource(R.drawable.black_border);
            imgLogo.setImageResource(R.drawable.building);
            Log.e("App","Failed to load company logo in onBitmapFailed method");
        }

        @Override
        public void onPrepareLoad(Drawable drawable) {
            imgLogo.setImageResource(R.drawable.loading);
            Log.e("App","Prepare to load company logo in onPrepareLoad method");
        }

    } 

@JakeWharton
Copy link
Member

Holy code...

You can't just call new Target() { ... } because there aren't any strong references to it. You need to store it on a field in a view holder or implement it on a subclass of a view or the like.

@zelongg
Copy link

zelongg commented Nov 23, 2016

@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());
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants