【问题标题】:Synchronous image loading on a background thread with Picasso - without .get()使用毕加索在后台线程上同步图像加载 - 没有 .get()
【发布时间】:2014-12-01 23:20:50
【问题描述】:

我有一个自定义视图组(包含毕加索加载的图像),可以在两个地方重复使用:

  1. 在应用程序中显示给用户(在 UI 线程上)
  2. 绘制到画布并保存为 .jpeg(在后台线程上)

我绘制到画布的代码如下所示:

int measureSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
view.measure(measureSpec, measureSpec);
Bitmap bitmap =
      Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.draw(canvas);

问题是在我将视图绘制到画布之前没有时间加载图像。我试图在这里尽可能地避免耦合,所以我不想添加 Picasso 回调,因为正在绘制的类对它正在绘制的视图一无所知。

我目前正在通过将图像加载代码更改为 .get() 而不是 .load() 然后使用 imageView.setImageBitmap() 来解决此问题。不幸的是,这给视图增加了很多复杂性,我真的不喜欢它。

我想做的是向 Picasso 的 RequestCreator 传递一个选项,即请求应该在当前线程上同步执行(如果它是主线程则抛出异常)。我想知道这对于直接内置到 Picasso 中的支持是否太过分了?还是它已经在 API 中而我没有注意到它?

【问题讨论】:

  • 您可以尝试为此使用自定义毕加索转换 - 将其添加为您的请求的一部分并运行您粘贴在那里的代码
  • 感谢您的想法 - 不过,该图像只是自定义视图组的一小部分,因此我不确定它是否适用于这种情况。
  • 啊,好的,很高兴您最终能够找到解决方案

标签: android picasso


【解决方案1】:

这是我的解决方案:

/**
 * Loads the request into an imageview.
 * If called from a background thread, the request will be performed synchronously.
 * @param requestCreator A request creator
 * @param imageView The target imageview
 * @param callback a Picasso callback
 */
public static void into(RequestCreator requestCreator, ImageView imageView, Callback callback) {
  boolean mainThread = Looper.myLooper() == Looper.getMainLooper();
  if (mainThread) {
    requestCreator.into(imageView, callback);
  } else {
    try {
      Bitmap bitmap = requestCreator.get();
      imageView.setImageBitmap(bitmap);
      if (callback != null) {
        callback.onSuccess();
      }
    } catch (IOException e) {
      if (callback != null) {
        callback.onError();
      }
    }
  }
}

【讨论】:

  • 您能解释一下您是如何使用它的吗?你如何获得请求创建者?谢谢
  • Picasso.load() 返回一个 RequestCreator。您在 RequestCreator 上调用 .into() 来创建实际的图像加载请求。
  • 您好,谢谢您的回答,很有帮助!!但是,你在回调中放了什么?我在这个时候放了null。
  • 回调是可选的。当您没有在主线程上运行并且异步加载图像并且想要成功或失败回调时使用它。
【解决方案2】:

Jacob Tabak 的完美答案

如果您将图像加载到Target 中,这是处理这种情况的一个小补充。我还没有找到一种方法来获取图像的来源以传递适当的LoadedFrom 参数。

 public static void into(RequestCreator requestCreator, Drawable placeHolder, Drawable errorDrawable, Target target) {
        boolean mainThread = Looper.myLooper() == Looper.getMainLooper();
        if (mainThread) {
            requestCreator.into(target);
        } else {
            try {
                target.onBitmapFailed(placeHolder);
                Bitmap bitmap = requestCreator.get();
                target.onBitmapLoaded(bitmap, Picasso.LoadedFrom.MEMORY);
            } catch (IOException e) {
                target.onBitmapFailed(errorDrawable);
            }
        }
    }

【讨论】:

    猜你喜欢
    • 2021-08-09
    • 2014-09-26
    • 2020-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-08
    • 2016-07-25
    相关资源
    最近更新 更多