簡體   English   中英

Picasso + RxJava2:方法調用應該從主線程發生

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

這是我最初的問題:

我試圖在AutoScrollViewPager顯示一些圖像。 我正在使用畢加索來實現同樣的目標。 但是,我想使用Rxjava2 + Picasso做同樣的事情。 我對這個RxJava概念有點新意。 因此,如果有人可以幫助我提供詳細信息,將下面的內容轉換為RxJava代碼,我會非常感激。

這是我在onViewCreated()onViewCreated()

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

這是我的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代碼? 任何幫助將不勝感激。

這就是我試圖做的事情

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);
                            }
                        });
       }
   });
}

但不幸的是,這不起作用,我最終得到了這個錯誤:

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)

任何幫助將不勝感激。 :)

你正在加載畢加索不允許的執行程序線程中的圖像(如果你問我,這是更好的方法來處理同步問題,但這就是現在的方式)。

您可以在此主題中查看此決定的詳細信息:

畢加索錯誤地允許外部調用者調用(而不是主線程)。 這些方法處理視圖回收和取消而不同步,因此在Picasso 2.3中我們添加了檢查。

有幾種選擇。 您可以在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