rxandroid要求在ui线程上运行,即使它是在AndroidSchedulers.mainThread()上订阅的

时间:2016-05-03 05:53:14

标签: android rx-java

我写了一个订阅者,当谷歌地图OnCameraChangeListener被触发时会被触发。

Observable.create(new Observable.OnSubscribe<LatLng>()
    {
        @Override
        public void call(Subscriber<? super LatLng> subscriber)
        {
            if (!subscriber.isUnsubscribed())
            {
                mMap.setOnCameraChangeListener(cameraPosition ->
                        subscriber.onNext(cameraPosition.target));
            }
        }
    }).subscribeOn(AndroidSchedulers.mainThread())
            .observeOn(AndroidSchedulers.mainThread())
            .onErrorResumeNext(Observable.<LatLng>empty())
            .debounce(1, TimeUnit.SECONDS)
            .subscribe(position -> {
                if (position.latitude != 0 && position.longitude != 0)
                {
                    updateLocationMarker(position);
                }
            });

我正在更新位置标记,如下所示:

private void updateLocationMarker(LatLng center)
{
    locationMarkertext.setText("Lat:" + center.latitude + " Long:" + center.longitude);
    //locationMarkerLayout.setVisibility(View.VISIBLE);
}

即使我的代码说要在AndroidSchedulers.mainThread()上运行,我也会收到此错误:

  

引起:rx.exceptions.OnErrorNotImplementedException:只有创建视图层次结构的原始线程才能触及其视图。

有人可以帮我理解我的方法有什么问题

2 个答案:

答案 0 :(得分:36)

默认情况下,运算符debounce在计算调度程序上运行,它将传递流经的事件。您必须使用主线程调度程序对其进行参数化:

.debounce(1, TimeUnit.SECONDS, AndroidSchedulers.mainThread())

此外,根据您创建通知来源的位置,您可能根本不需要observeOnsubscribeOn

答案 1 :(得分:0)

接受的答案不是正确的方法。正确的做法是在 observeOn(AndroidSchedulers.mainThread())之后放置debounce(1, TimeUnit.SECONDS) 。所以你的代码变成了:

Observable.create(new Observable.OnSubscribe<LatLng>()
    {
        @Override
        public void call(Subscriber<? super LatLng> subscriber)
        {
            if (!subscriber.isUnsubscribed())
            {
                mMap.setOnCameraChangeListener(cameraPosition ->
                        subscriber.onNext(cameraPosition.target));
            }
        }
    }).subscribeOn(AndroidSchedulers.mainThread())
            .onErrorResumeNext(Observable.<LatLng>empty())
            .debounce(1, TimeUnit.SECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(position -> {
                if (position.latitude != 0 && position.longitude != 0)
                {
                    updateLocationMarker(position);
                }
            });

去抖动应该在ComputationScheduler而不是主线程上运行。