Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 浓缩咖啡等待[RxIdlingResource]变为空闲超时_Android_Android Testing_Android Espresso_Rx Android - Fatal编程技术网

Android 浓缩咖啡等待[RxIdlingResource]变为空闲超时

Android 浓缩咖啡等待[RxIdlingResource]变为空闲超时,android,android-testing,android-espresso,rx-android,Android,Android Testing,Android Espresso,Rx Android,我对浓缩咖啡测试还不熟悉。在我现有的应用程序中,我们使用RxAndroid进行一些联网。我们使用RxBus与应用程序中看似“不可能”的部分进行通信 我们导入了实现idlingsource的,这样我们就可以使用RxAndroid网络调用 不幸的是,它不允许RxBus工作,因为它是一个“热可观测”且从不关闭。因此,它抛出android.support.test.espresso.idlingsourcetimeoutexception:等待[RxIdlingResource]变为空闲超时 我制作了一

我对浓缩咖啡测试还不熟悉。在我现有的应用程序中,我们使用RxAndroid进行一些联网。我们使用RxBus与应用程序中看似“不可能”的部分进行通信

我们导入了实现
idlingsource
的,这样我们就可以使用RxAndroid网络调用

不幸的是,它不允许RxBus工作,因为它是一个“热可观测”且从不关闭。因此,它抛出
android.support.test.espresso.idlingsourcetimeoutexception:等待[RxIdlingResource]变为空闲超时

我制作了一个小的Android应用程序来证明我的观点。 它有两项活动。第一个显示启动时通过网络调用在
RecyclerView
中检索到的一些项目

当点击它时,它会通过RxBus进行通信(我知道这有点过分,但纯粹是为了证明这一点)。然后,
DetailActivity
显示数据

我们如何进行编辑以使其与RxBus配合使用

RxIdlingResource也可以检查

/**
*为RxJava和Espresso提供挂钩,以便Espresso知道何时等待
*直到RxJava订阅完成。
*/
公共最终类RxIdlingResource扩展RxJavaObservableExecutionHook实现IDlingSource{
公共静态最终字符串TAG=“RxIdlingResource”;
静态日志级别LOG_LEVEL=无;
私有最终AtomicInteger订阅=新的AtomicInteger(0);
私有静态资源实例;
私有资源回调;
私有资源{
//私人的
}
公共静态RxIdlingResource get(){
if(实例==null){
实例=新的RxIdlingResource();
浓缩咖啡注册资源(实例);
}
返回实例;
}
/* ======================== */
/*IdlingResource覆盖*/
/* ======================== */
@凌驾
公共字符串getName(){
返回标签;
}
@凌驾
公共布尔值isIdleNow(){
int-activeSubscriptionCount=subscriptions.get();
布尔isIdle=activeSubscriptionCount==0;
if(日志级atOrAbove(调试)){
Log.d(标记“activeSubscriptionCount:+activeSubscriptionCount”);
Log.d(标签“isIdleNow:+isIdle”);
}
返回isIdle;
}
@凌驾
公共无效RegisterIDletionCallback(ResourceCallback ResourceCallback){
if(日志级atOrAbove(调试)){
d(标记“registeridletioncallback”);
}
this.resourceCallback=resourceCallback;
}
/* ======================================= */
/*RxJavaObservableExecutionHook重写*/
/* ======================================= */
@凌驾

public Observable.on Subscribe on SubscribeStart(Observable由于我们没有得到这个问题的任何更好的答案,我们假设通过RxBus发送的
对象是即时的,不需要计入
订阅中。incrementAndGet();

我们只是在这一行之前过滤掉对象。在我们的例子中,对象属于类
SerializedSubject
PublishSubject

这是我们改变的方法

@Override
public <T> Observable.OnSubscribe<T> onSubscribeStart(Observable<? extends T> observableInstance, final Observable.OnSubscribe<T> onSubscribe) {

    int activeSubscriptionCount = 0;

    if (observableInstance instanceof SerializedSubject || observableInstance instanceof PublishSubject) {
        Log.d(TAG, "Observable we won't register: " + observableInstance.toString());
    } else {
        activeSubscriptionCount = subscriptions.incrementAndGet();
    }
    if (LOG_LEVEL.atOrAbove(DEBUG)) {
        if (LOG_LEVEL.atOrAbove(VERBOSE)) {
            Log.d(TAG, onSubscribe + " - onSubscribeStart: " + activeSubscriptionCount, new Throwable());
        } else {
            Log.d(TAG, onSubscribe + " - onSubscribeStart: " + activeSubscriptionCount);
        }
    }


    onSubscribe.call(new Subscriber<T>() {
        @Override
        public void onCompleted() {
            onFinally(onSubscribe, "onCompleted");
        }

        @Override
        public void onError(Throwable e) {
            onFinally(onSubscribe, "onError");
        }

        @Override
        public void onNext(T t) {
            Log.d(TAG, "onNext:: " + t.toString());
            //nothing
        }
    });

    return onSubscribe;
}
@覆盖
公共可观测的,可观测的
public class RxBus {

    //private final PublishSubject<Object> _bus = PublishSubject.create();

    // If multiple threads are going to emit events to this
    // then it must be made thread-safe like this instead
    private final Subject<Object, Object> _bus = new SerializedSubject<>(PublishSubject.create());

    public void send(Object o) {
        _bus.onNext(o);
    }

    public Observable<Object> toObserverable() {
        return _bus;
    }

    public boolean hasObservers() {
        return _bus.hasObservers();
    }
}
public class MainActivity extends AppCompatActivity {

    @Bind(R.id.rv)
    RecyclerView RV;

    private List<NewsItem> newsItems;
    private RecyclerViewAdapter adapter;
    private Observable<List<NewsItem>> newsItemsObservable;
    private CompositeSubscription subscriptions = new CompositeSubscription();
    private RxBus rxBus;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        //Subscribe to RxBus
        rxBus = new RxBus();
        subscriptions.add(rxBus.toObserverable()
                .subscribe(new Action1<Object>() {
                    @Override
                    public void call(Object event) {
                        //2.
                        NewsItem myClickNewsItem = (NewsItem) event;
                        startActivity(new Intent(MainActivity.this, DetailActivity.class).putExtra("text", myClickNewsItem.getBodyText()));
                    }
                }));

        //Set the adapter
        adapter = new RecyclerViewAdapter(this);
        //Set onClickListener on the list
        ItemClickSupport.addTo(RV).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
            @Override
            public void onItemClicked(RecyclerView recyclerView, int position, View v) {
                //Send the clicked item over the RxBus.
                //Receives it in 2.
                rxBus.send(newsItems.get(position));
            }
        });
        RV.setLayoutManager(new LinearLayoutManager(this));
        RestAdapter retrofit = new RestAdapter.Builder()
                .setEndpoint("http://URL.com/json")
                .build();
        ServiceAPI api = retrofit.create(ServiceAPI.class);
        newsItemsObservable = api.listNewsItems(); //onComplete goes to setNewsItems
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        NewsItemObserver observer = new NewsItemObserver(this);
        newsItemsObservable.delaySubscription(1, TimeUnit.SECONDS).observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()).subscribe(observer);
    }

    public void setNewsItems(List<NewsItem> newsItems) {
        this.newsItems = newsItems;
        adapter.setNewsItems(newsItems);
        RV.setAdapter(adapter);
    }
@Override
public <T> Observable.OnSubscribe<T> onSubscribeStart(Observable<? extends T> observableInstance, final Observable.OnSubscribe<T> onSubscribe) {

    int activeSubscriptionCount = 0;

    if (observableInstance instanceof SerializedSubject || observableInstance instanceof PublishSubject) {
        Log.d(TAG, "Observable we won't register: " + observableInstance.toString());
    } else {
        activeSubscriptionCount = subscriptions.incrementAndGet();
    }
    if (LOG_LEVEL.atOrAbove(DEBUG)) {
        if (LOG_LEVEL.atOrAbove(VERBOSE)) {
            Log.d(TAG, onSubscribe + " - onSubscribeStart: " + activeSubscriptionCount, new Throwable());
        } else {
            Log.d(TAG, onSubscribe + " - onSubscribeStart: " + activeSubscriptionCount);
        }
    }


    onSubscribe.call(new Subscriber<T>() {
        @Override
        public void onCompleted() {
            onFinally(onSubscribe, "onCompleted");
        }

        @Override
        public void onError(Throwable e) {
            onFinally(onSubscribe, "onError");
        }

        @Override
        public void onNext(T t) {
            Log.d(TAG, "onNext:: " + t.toString());
            //nothing
        }
    });

    return onSubscribe;
}