2017-01-28 59 views
3

發生這是我最初的問題:畢加索+ RxJava2:方法調用應該從主線程

我試圖展現在AutoScrollViewPager一些圖片。我正在使用畢加索來達到同樣的效果。不過,我想用Rxjava2 + Picasso做同樣的事情。我對這個RxJava概念有點新鮮。所以如果任何人都可以幫我細節,如果可能的話,將下面的代碼轉換成RxJava代碼,我會非常感激。

這是我在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了一下:

@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) 

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

+0

如果刪除'.subscribeOn什麼(調度器.newThread())'?錯誤說「方法調用應該從主線程發生」,但是你告訴你的代碼在新線程上訂閱。或者'.subscribeOn(AndroidSchedulers.mainThread())',這可能是一樣的... – JonesV

回答

3

您正在從執行程序線程加載圖像,畢加索不允許(如果問我,這是傾向選擇,有更好的方法來處理同步問題,但現在是這樣) 。

你可以看到這個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.

有你幾個選項。你可以做全instantiateItem工作在UI線程,如果你通過Looper.getMainLooper(),或者您可以使用RequestCreator.get()方法,而不是RequestCreator.into(),或包裝你Picasso工作:

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