本文介绍了Picasso + RxJava2:方法调用应从主线程进行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我最初的问题:

我正在尝试在AutoScrollViewPager中显示一些图像.我正在使用毕加索来实现相同目的.但是,我想使用Rxjava2 + Picasso进行相同的操作.我对RxJava概念有点陌生.因此,如果有人可以在可能的情况下帮助我,将下面的内容转换为RxJava代码,我将非常感激.

I am trying to show a few images in the AutoScrollViewPager. I am using Picasso to achieve the same. However, I would like to do the same with using Rxjava2 + Picasso. I am kinda new to this RxJava concept. So if anyone can help me with details if possible, to convert the below into RxJava code, I would really appreciate it.

这就是我在onViewCreated()

This is what I do in onViewCreated()

imageAdapter = new ImageAdapter(getActivity());
autoScrollViewPager.setAdapter(imageAdapter);
autoScrollViewPager.setCurrentItem(imageAdapter.getCount() - 1);
autoScrollViewPager.startAutoScroll();
autoScrollViewPager.setInterval(4000);

这是我的ImageAdapter

This is my ImageAdapter

ImageAdapter(Context context){
    this.context=context;
    mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
    return GalImages.length;
}

@Override
public boolean isViewFromObject(View view, Object object) {
    return view == ((RelativeLayout) object);
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
    LayoutInflater inflater = (LayoutInflater) container.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.pager_item,null);
    ((ViewPager) container).addView(view);
    final ImageView img = (ImageView) view.findViewById(R.id.imageView);
    Picasso.with(context)
            .load(GalImages[position])
            .fit()
            .into(img);
    return view;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    container.removeView((RelativeLayout)object);
}

如何将其转换为RxJava代码?任何帮助将不胜感激.

How can I convert this into RxJava code? Any help will be appreciated.

这是我试图做的

我稍微更改了ImageAdapter:

@Override
public Object instantiateItem(ViewGroup container, int position) {
    LayoutInflater inflater = (LayoutInflater) container.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.pager_item,null);
    ((ViewPager) container).addView(view);
    img = (ImageView) view.findViewById(R.id.imageView);
    loadImagesWithPicasso(position)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe();
    return view;
}

public Completable loadImagesWithPicasso(int position) {
   return Completable.fromAction(new Action() {
       @Override
       public void run() throws Exception {
           Picasso.with(context)
                  .load(GalImages[position])
                  .fit()
                  .into(new Target() {
                            @Override
                            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {

                            }

                            @Override
                            public void onBitmapFailed(Drawable errorDrawable) {

                            }

                            @Override
                            public void onPrepareLoad(Drawable placeHolderDrawable) {
                                img.setImageDrawable(placeHolderDrawable);
                            }
                        });
       }
   });
}

但是不幸的是,这没有用,我最终遇到了这个错误:

But this, unfortunately, did not work and I ended up with this error:

java.lang.IllegalStateException: Method call should happen from the main thread.
at com.squareup.picasso.Utils.checkMain(Utils.java:136)
at com.squareup.picasso.RequestCreator.into(RequestCreator.java:496)
at com.kaaddevelopers.myprescriptor.ImageAdapter$1.run(ImageAdapter.java:79)
at io.reactivex.internal.operators.completable.CompletableFromAction.subscribeActual(CompletableFromAction.java:34)
at io.reactivex.Completable.subscribe(Completable.java:1613)
at io.reactivex.internal.operators.completable.CompletableSubscribeOn$SubscribeOnObserver.run(CompletableSubscribeOn.java:64)
at io.reactivex.Scheduler$1.run(Scheduler.java:134)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:59)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:51)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)

任何帮助将不胜感激. :)

Any help will be appreciated. :)

推荐答案

您正在从executor线程加载图像,这是Picasso不允许的(如果您问我,这是一个不错的选择,有更好的处理方法同步问题,但这就是现在的方式.

You are loading the image from the executor thread, which Picasso doesn't allow (this is pour choice if you ask me, there are better ways to deal with sync issues, but that's the way it is now).

您可以在此线程中看到该决定的详细信息:

有几个选项供您选择.如果传入Looper.getMainLooper(),则可以在UI线程中完成整个instantiateItem工作,或者可以使用RequestCreator.get()方法而不是RequestCreator.into()或将Picasso工作包装为:

There are several options for you. You can do the whole instantiateItem work in the UI thread, if you pass Looper.getMainLooper() in, or you can use RequestCreator.get() method instead of RequestCreator.into(), or wrap your Picasso work with:

context.runOnUiThread(new Runnable() {
    @Override
    public void run() {
         // Can call RequestCreator.into here
    }
});

这篇关于Picasso + RxJava2:方法调用应从主线程进行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 04:39