为什么Picasso在后台线程中运行阻止onActivityResult?

Gab*_*iel 2 multithreading android picasso

我们正在为应用中的照片创建共享模式,其中一个共享选项是在线加载图像的叠加层.如果用户在叠加完成加载之前共享照片,我们将使用未修改的图像发送意图以使用startActivityForResult与其他应用共享,然后在onActivityResult中,我们将用户从共享视图返回到普通照片视图.

我们遇到的问题是,当用户从共享照片返回时,在加载覆盖的后台线程完成之前,不会调用onActivityResult.是否有原因导致后台线程突然开始阻止UI线程?

以下是我们在overlay视图类中使用的代码,它扩展了ImageView来管理它:

private void asyncLoadImage() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            loadImage();
        }
    }).start();
}

private void loadImage() {
    try {
        overlayBitmap = Picasso.with(getContext()).load(url).get();
        if (overlayBitmap != null) {
            displayBitmap();
        } else {
            displayError();
        }

    } catch (IOException ignored) {
        displayError();
    }
}
Run Code Online (Sandbox Code Playgroud)

我们已经尝试过使用Picasso目标,而不是创建我们自己的线程,我们遇到了完全相同的问题,到目前为止唯一的解决方案是异步使用Ion(但是,在我们之前使用Ion同步或尝试取消Ion请求期货调用startActivityForResult导致相同的UI线程阻塞问题).这感觉就像一个巨大的黑客,因为我们在应用程序中的其他地方使用毕加索.

这些后台任务在返回活动时是否会阻止UI线程?

Lor*_*ous 6

查看代码,您将在不需要时创建新线程.Picasso有一个可配置的线程执行器方法.

当使用毕加索加载超过100个图像时我遇到了一个问题,它会锁定并阻止我的UI线程,但这是因为每次我调用毕加索来获取图像时都会创建一个新线程.我通过做一些研究解决了这个问题,并发现在毕加索内部有一个可配置的执行器方法.

这是我的ImageHandler类实现

public class ImageHandler {

private static Picasso instance;

public static Picasso getSharedInstance(Context context)
{
    if(instance == null)
    {
        instance = new Picasso.Builder(context).executor(Executors.newSingleThreadExecutor()).memoryCache(Cache.NONE).indicatorsEnabled(true).build();
        return instance;
    }
    else
    {
        return instance;
    }
}
}
Run Code Online (Sandbox Code Playgroud)

我不知道这是你的问题,但如果你还没有实现它,那将值得一试.
这是我用它来加载图像的方式

    ImageHandler.getSharedInstance(getApplicationContext()).load(imString).skipMemoryCache().resize(width, height).into(image, new Callback() {
        @Override
        public void onSuccess() {
            layout.setVisibility(View.VISIBLE);
        }

        @Override
        public void onError() {

        }
    });
Run Code Online (Sandbox Code Playgroud)