2017-01-28 35 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 
    } 
}); 
相关问题