When I use RxAndroid and .observeOn(AndroidSchedulers.mainThread()) and run the tests on the emulator using Android Studio, the whole test run crashes with:
Toolkit error due to ' java.lang.NoSuchMethodError '
and logcat are output as follows:
FATAL EXCEPTION: main java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread. at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:54) at android.os.Handler.handleCallback(Handler.java:587) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:123) at android.app.ActivityThread.main(ActivityThread.java:4627) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:521) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.NoSuchMethodError: rx.internal.schedulers.ScheduledAction.lazySet at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:46) ... 9 more Error in app net.tbmcv.rxtest running instrumentation ComponentInfo{net.tbmcv.rxtest.test/android.test.InstrumentationTestRunner}: java.lang.NoSuchMethodError java.lang.NoSuchMethodError: rx.internal.schedulers.ScheduledAction.lazySet Force stopping package net.tbmcv.rxtest uid=10042
Neither Android Studio nor the logcat output mentions lines of code in my project or my tests. Here are some relevant parts of the short example project that I created that reproduces this glitch:
app/build.gradle
dependencies { compile 'io.reactivex:rxandroid:0.24.0' }
MainActivity.java
public class MainActivity extends Activity { public void setTitleFrom(Observable<String> observable) { observable.observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<String>() { @Override public void call(String s) { setTitle(s); } }); } }
MainActivityFuncTest.java
public class MainActivityFuncTest extends ActivityInstrumentationTestCase2<MainActivity> { public void testSetTitle() { final String newTitle = "Hello World"; getActivity().setTitleFrom(Observable.just(newTitle)); getInstrumentation().waitForIdleSync(); assertEquals(newTitle, getActivity().getTitle()); } }
My test runs correctly if I modify the MainActivity code so as not to use observeOn() :
public void setTitleFrom(Observable<String> observable) { observable.subscribe(new Action1<String>() { @Override public void call(final String s) { runOnUiThread(new Runnable() { @Override public void run() { setTitle(s); } }); } }); }
But I would prefer to use observeOn() because it is cleaner and more modular. How can I run my tests?
My emulator runs API version 8 (Android 2.2).
source share