使用 observeOn() Android UI 线程使我的模拟器测试崩溃
Using observeOn() the Android UI thread crashes my emulator testing
当我使用 RxAndroid 和 .observeOn(AndroidSchedulers.mainThread())
,以及使用 Android Studio 在模拟器上进行 运行 测试时,整个测试 运行 崩溃:
Instrumentation run failed due to 'java.lang.NoSuchMethodError
'
和logcat
输出如下:
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
Android Studio 和 logcat
输出均未提及我的项目或测试中的任何代码行。以下是我创建的重现此崩溃的简短示例项目的一些相关部分:
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());
}
}
如果我将我的 MainActivity
代码修改为不使用 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);
}
});
}
});
}
但我宁愿使用 observeOn()
,因为它更简洁且更模块化。我怎样才能让我的测试达到 运行?
我的模拟器是 运行ning API 版本 8 (Android 2.2).
根据RxJava's GitHub page,RxJava versions 1.0.x 仅适用于Android 2.3 或更高版本(对应于API 9 或更高版本)。当然,RxAndroid 依赖于 RxJava,所以同样的限制也适用(尽管目前 RxAndroid 页面上没有提到它。)
以上测试 运行 在模拟器 运行 上使用较新版本的 Android。
当我使用 RxAndroid 和 .observeOn(AndroidSchedulers.mainThread())
,以及使用 Android Studio 在模拟器上进行 运行 测试时,整个测试 运行 崩溃:
Instrumentation run failed due to '
java.lang.NoSuchMethodError
'
和logcat
输出如下:
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
Android Studio 和 logcat
输出均未提及我的项目或测试中的任何代码行。以下是我创建的重现此崩溃的简短示例项目的一些相关部分:
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());
}
}
如果我将我的 MainActivity
代码修改为不使用 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);
}
});
}
});
}
但我宁愿使用 observeOn()
,因为它更简洁且更模块化。我怎样才能让我的测试达到 运行?
我的模拟器是 运行ning API 版本 8 (Android 2.2).
根据RxJava's GitHub page,RxJava versions 1.0.x 仅适用于Android 2.3 或更高版本(对应于API 9 或更高版本)。当然,RxAndroid 依赖于 RxJava,所以同样的限制也适用(尽管目前 RxAndroid 页面上没有提到它。)
以上测试 运行 在模拟器 运行 上使用较新版本的 Android。