【问题标题】:Using observeOn() the Android UI thread crashes my emulator testing使用 observeOn() Android UI 线程使我的模拟器测试崩溃
【发布时间】:2015-06-20 20:02:18
【问题描述】:

当我使用 RxAndroid 和 .observeOn(AndroidSchedulers.mainThread()),并使用 Android Studio 在模拟器上运行测试时,整个测试运行崩溃:

由于“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(),因为它更简洁、更模块化。如何让我的测试运行?

我的模拟器运行的是 API 版本 8 (Android 2.2)。

【问题讨论】:

  • 模拟器好像有版本错误。 AtomicReference.lazySet 是一个非常标准的 Java 6 方法。
  • @akarnokd 谢谢,就是这样!我的模拟器运行 API 8,而 RxJava 仅适用于 API 9+。 RxAndroid 的页面根本没有提到 API 版本限制,我猜是因为它已经在 RxJava 页面上提到了。想写一个答案让我接受吗?
  • 使用io.reactivex:rxandroid:1.0.1
  • @IgorGanapolsky 真的可以解决下面答案中描述的 Android 版本不兼容问题吗?
  • @DanGetz 好问题。我只是在观察你的 build.gradle 文件。

标签: java android android-studio rx-java rx-android


【解决方案1】:

根据RxJava's GitHub page,RxJava 1.0.x 版本仅适用于 Android 2.3 或更高版本(对应 API 9 或更高版本)。当然,RxAndroid 依赖于 RxJava,所以同样的限制也适用(尽管目前 RxAndroid 页面上没有提到它。)

上述测试在运行更新版本 Android 的模拟器上运行良好。

【讨论】:

    猜你喜欢
    • 2020-06-05
    • 2020-11-13
    • 2023-01-21
    • 2012-09-13
    • 1970-01-01
    • 1970-01-01
    • 2018-11-04
    • 2014-02-20
    • 1970-01-01
    相关资源
    最近更新 更多