【问题标题】:Picasso onBitmapLoaded never calledPicasso onBitmapLoaded 从未调用过
【发布时间】:2014-11-16 11:22:18
【问题描述】:

我遇到了同样的问题,我想使用 Picasso 生成的可绘制对象来进行图像缓存,但我无法获得相同的结果。这是我用来访问位图可绘制对象的代码:

Target targetBitmap = new Target() {

            @Override
            public void onPrepareLoad(Drawable arg0) {

            }

            @Override
            public void onBitmapLoaded(Bitmap arg0, Picasso.LoadedFrom arg1) {
                mBitmap = arg0;
                BitmapDrawable d = new BitmapDrawable(context.getResources(), arg0);

                int margin = 2;
                int border = 0;

                Rect r = new Rect(margin, margin, width - margin, height - margin);

                int imageWidth = r.width();
                int imageHeight = r.height();

                if (imageHeight > r.height() - (border * 2)) {
                    imageHeight = r.height() - (border * 2);
                }

                r.left += ((r.width() - imageWidth) / 2) - border;
                r.right = r.left + imageWidth + border + border;
                r.top += ((r.height() - imageHeight) / 2) + border;
                r.bottom = r.top + imageHeight + border + border;

                Paint p = new Paint();
                p.setColor(0xFFFFFF);

                c.drawRect(r, p);
                r.left += border;
                r.right -= border;
                r.top += border;
                r.bottom -= border;
                d.setBounds(r);
                d.draw(c);
            }

            @Override
            public void onBitmapFailed(Drawable arg0) {

            }
        };

        Picasso.with(context).load(app.getListBookDetails().get(img_num).getImage_150x225()).into(targetBitmap);

但是这里永远不会调用 onBitmapLoaded 方法。如何访问此方法?如果可以的话请帮忙。我什么都抓了,但都是徒劳的。

谢谢 萨纳特

【问题讨论】:

  • 如果你在毕加索电话之前添加Log.d("myapp", app.getListBookDetails().get(img_num).getImage_150x225());这行代码是什么意思?
  • 它显示了我使用毕加索的图像 URL。
  • 你的应用有网络权限吗?放
  • 是的,当然图片在我不使用毕加索时显示,但我必须将其缓存在磁盘中,这就是我想使用相同的原因。
  • 如果那是您的确切代码,targetBitmap 将被垃圾回收,因为 Picasso 持有对它的弱引用。您需要将其移动为字段或在视图或其他东西上实现以防止这种情况发生。

标签: android android-drawable picasso


【解决方案1】:

如果您想防止 Target 对象被垃圾收集,下面是示例代码:

 final Target mTarget = new Target() {
                        @Override
                        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) {
                            Log.d("DEBUG", "onBitmapLoaded");
                            BitmapDrawable mBitmapDrawable = new BitmapDrawable(getResources(), bitmap);
                            navigationMenuItem.setIcon(mBitmapDrawable);
                        }

                        @Override
                        public void onBitmapFailed(Drawable drawable) {
                            Log.d("DEBUG", "onBitmapFailed");
                        }

                        @Override
                        public void onPrepareLoad(Drawable drawable) {
                            Log.d("DEBUG", "onPrepareLoad");
                        }
                    };


                    Picasso.with(this).load(tempUrl).into(mTarget);

【讨论】:

  • @AdamJohns 我已将 Target 对象设为 final 以防止它被垃圾回收
  • 这行不通:final 表示本地变量在语言级别是不可更改的,但这并不妨碍当变量的可见范围结束时被引用的对象被并发 GC 收集.
  • 请检查它的范围不是本地的它的实例变量@Miha_x64 所以它不会被GC标记为JW在cmets中所说的
  • @Shubham 从您的代码中不清楚。 final Target mTarget = ... 应该是一个类字段——好的,但是,首先,从类范围来看,navigationMenuItem 变量可能是不可用的;第二,Picasso.with(...)...final Target target 并列,并没有说这部分代码必须位于不同的位置(mTarget 在类体中,Picasso.with(...) - 在方法体中;第三,如果mTarget 是一个字段,它不能是final,当不再需要它时,它必须被清空才能被GCed。
【解决方案2】:

为了让位图在 RxJava 2 中使用下一个:

fun getBitmapSingle(picasso: Picasso, url: String): Single<Bitmap> = Single.create {
    try {
        if (!it.isDisposed) {
            val bitmap: Bitmap = picasso.load(url).get()
            it.onSuccess(bitmap)
        }
    } catch (e: Throwable) {
        it.onError(e)
    }
}

检索位图:

getBitmapSingle(Picasso.with(context), "https:/...")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ bitmap ->
                // val drawable = BitmapDrawable(context, bitmap)
                }, Throwable::printStackTrace)

【讨论】:

  • get()方法有问题:它的结果没有缓存:> 注意:这个操作的结果没有缓存在内存中,因为底层的Cache实现不保证是线程的——安全。
  • @cVoronin 感谢您的评论。就我而言,一切正常。您是否尝试更改缓存实现。我发现缓存保存在本地存储中。
猜你喜欢
  • 2016-02-09
  • 2016-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-23
  • 1970-01-01
  • 2014-11-23
相关资源
最近更新 更多