android - picasso 可以帮我排队吗?

标签 android image picasso android-image image-loading

这是关于 picasso 行为的一个关键点,我不知道。

假设您正在放映包含 10 个项目的幻灯片。比如说,他们每人在屏幕上停留十秒钟。

理想的行为是这样的:在幻灯片放映开始时,我只需执行以下操作:

picasso.get( url1 )
picasso.get( url2 )
picasso.get( url3 )
picasso.get( url4 )
picasso.get( url5 )
picasso.get( url6 )
picasso.get( url7 )
picasso.get( url8 )
picasso.get( url9 )
picasso.get( url10 )

而且,事实上, picasso 会在队列中一次做一个

如果我告诉 Picasso 一次预热 10 个 url,它的行为是什么?

是否可以让 Picasso 按顺序一次只做一件事情 - 有这样的选择吗?

(另外一个问题是,你能不能取消排队,或者……?)


壁画

感谢@alicanozkara 在这个页面上的惊人回答,我第一次了解到

https://github.com/facebook/fresco

(13k 星)无论好坏,我认为 picasso 时代可能已经结束。

最佳答案

Is it possible to have Picasso do things only one at a time, in order - is there such an option?

我不确定它可以用 Picasso 本身来完成,但至少 RxJava 可能适用于这个问题。

我将发布一段带有评论的代码:

public class MainActivity extends AppCompatActivity {

    public static final List<String> urlList = Arrays.asList(
            "http://i.imgur.com/UZFOMzL.jpg",
            "http://i.imgur.com/H981AN7.jpg",
            "http://i.imgur.com/nwhnRsZ.jpg",
            "http://i.imgur.com/MU2dD8E.jpg"
    );

    List<Target> targetList = new ArrayList<>();
    List<Completable> completables = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final long start = System.currentTimeMillis();
        // emit each url separately
        Observable.fromIterable(urlList)
                // flatmap to an Observable<Completable>
                .flatMap(url ->
                        // fromCallable ensures that this stream will emit value as soon as it is subscribed
                        // Contrary to this, Observable.just() would emit immediately, which we do not want
                        Observable.fromCallable(() ->
                                // We need to know whether either download is
                                // completed or no, thus we need a Completable
                                Completable.create(e -> {
                                    Target target = new Target() {
                                        @Override
                                        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                                            Log.i("vvv", "downloaded " + url + ", " + (System.currentTimeMillis() - start));
                                            e.onComplete();
                                        }

                                        @Override
                                        public void onBitmapFailed(Drawable errorDrawable) {
                                            e.onError(new IllegalArgumentException("error happened"));
                                        }

                                        @Override
                                        public void onPrepareLoad(Drawable placeHolderDrawable) {

                                        }
                                    };
                                    // need to keep a strong reference to Target, because Picasso holds weak reference
                                    targetList.add(target);
                                    Picasso.with(MainActivity.this)
                                            .load(url)
                                            .into(target);
                                })))
                // collecting all Completables into a list
                .collectInto(completables, List::add)
                // flatmap-ing this Observable into a Completable, concatenating each completable
                // to next, thus they will be downloaded in order
                .flatMapCompletable(Completable::concat)
                // clearing the strong reference we retained earlier
                .doFinally(() -> {
                    targetList.clear();
                    targetList = null;
                })
                .subscribe(
                        () -> Log.i("vvv", "done: " + (System.currentTimeMillis() - start)),
                        throwable -> Log.e("vvv", "err " + throwable.getMessage()
                        ));
    }

}

这将是 logcat 中的输出:

enter image description here

这是理想情况,当每个图像都成功加载时。当无法加载其中一张图像时,此代码段不处理这种情况。一旦 Picasso 无法加载其中之一 - 流将被中断并调用 onError()

关于android - picasso 可以帮我排队吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46131941/

相关文章:

android - Logcat 错误 E/MediaPlayer : Should have subtitle controller already set

html - 启用自动调整图像大小

android - picasso 不加载图像

java - 在 Picasso Target 中调用 setImageBitmap 时不重绘 ImageView

android - 错误 : Unable to resolve dependency for ':react-native-maps@debug/compileClasspath' : Could not resolve androidx. appcompat :appcompat:1. 0.0

android - 标题栏不显示在模拟器上但显示在 eclipse 中?

android - 如何在android中将视频格式mov转换为3gp或mp4

javascript - 在 JavaScript 中将图像十六进制转换为 base64

java - 如何仅将部分图像用于 LWJGL

android - 使用 Picasso 将位图加载到循环中的菜单项