gpt4 book ai didi

java - picasso + RxJava2 : Method call should happen from the main thread

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:44:56 27 4
gpt4 key购买 nike

这是我最初的问题:

我试图在 AutoScrollViewPager 中显示一些图像。我正在使用 Picasso 来达到同样的目的。但是,我想使用 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)

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

最佳答案

您正在从执行线程加载图像,这是 Picasso 不允许的(如果您问我,这是一个很好的选择,有更好的方法来处理同步问题,但现在就是这样)。

可以看到这个决定的详细信息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.

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

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

关于java - picasso + RxJava2 : Method call should happen from the main thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41908613/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com