简体   繁体   English

Picasso + RxJava2:方法调用应该从主线程发生

[英]Picasso + RxJava2: Method call should happen from the main thread

This was my initial Question: 这是我最初的问题:

I am trying to show a few images in the AutoScrollViewPager . 我试图在AutoScrollViewPager显示一些图像。 I am using Picasso to achieve the same. 我正在使用毕加索来实现同样的目标。 However, I would like to do the same with using Rxjava2 + Picasso. 但是,我想使用Rxjava2 + Picasso做同样的事情。 I am kinda new to this RxJava concept. 我对这个RxJava概念有点新意。 So if anyone can help me with details if possible, to convert the below into RxJava code, I would really appreciate it. 因此,如果有人可以帮助我提供详细信息,将下面的内容转换为RxJava代码,我会非常感激。

This is what I do in onViewCreated() 这是我在onViewCreated()onViewCreated()

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

This is my ImageAdapter 这是我的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);
}

How can I convert this into RxJava code? 如何将其转换为RxJava代码? Any help will be appreciated. 任何帮助将不胜感激。

This is what I tried to do 这就是我试图做的事情

I changed my ImageAdapter a bit: ImageAdapter改变了我的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. 任何帮助将不胜感激。 :) :)

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). 你正在加载毕加索不允许的执行程序线程中的图像(如果你问我,这是更好的方法来处理同步问题,但这就是现在的方式)。

You can see the details of this decision in this thread : 您可以在此主题中查看此决定的详细信息:

It was a mistake from Picasso to allow external callers to invoke into() other than the main thread. 毕加索错误地允许外部调用者调用(而不是主线程)。 Those methods deal with view recycling and canceling without synchronization, hence in Picasso 2.3 we added the checks. 这些方法处理视图回收和取消而不同步,因此在Picasso 2.3中我们添加了检查。

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: 您可以在UI线程中执行整个instantiateItem工作,如果您传入Looper.getMainLooper() ,或者您可以使用RequestCreator.get()方法而不是RequestCreator.into() ,或者将Picasso包装为:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM