后台线程

时间:2015-10-27 20:26:52

标签: rx-java rx-android

我正在使用 RxAndroid 进行流操作。在我的实际用例中,我从服务器获取一个列表(使用 Retrofit )。我正在使用调度程序在后台线程上完成工作,并在Android UI(主)线程上获得最终发布。

这适用于网络调用,但我意识到网络调用后我的运算符不使用后台线程,而是在主线程上调用。

myService.fetchSomeIntegersFromServer()
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .filter(integer -> {
            System.out.println(Looper.getMainLooper().getThread() == Thread.currentThread());
            return true;
        })
        .subscribe(integer1 -> {});

如何确保所有操作都在后台线程上执行?

1 个答案:

答案 0 :(得分:56)

TL; DR :将observeOn(AndroidSchedulers.mainThread())移到filter(...)以下。

subscribeOn(...)用于指定Observable开始操作的线程。对subscribeOn的后续调用将被忽略。

因此,如果您要编写以下内容,所有将在Schedulers.newThread()上执行:

myService.fetchSomeIntegersFromServer()
        .subscribeOn(Schedulers.newThread())
        .filter(integer -> {
            System.out.println(Looper.getMainLooper().getThread() == Thread.currentThread());
            return true;
        })
        .subscribe(integer1 -> { doSomething(integer1); });

现在,当然,这不是你想要的:你想在主线程上doSomething 这就是observeOn到位的地方。 observeOn之后的所有操作都在该调度程序上执行。因此,在您的示例中,filter在主线程上执行。

相反,请将observeOn向下移至subscribe之前:

myService.fetchSomeIntegersFromServer()
        .subscribeOn(Schedulers.newThread())
        .filter(integer -> {
            System.out.println(Looper.getMainLooper().getThread() == Thread.currentThread());
            return true;
        })
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(integer1 -> { doSomething(integer1) });

现在,filter将在'新主题'上发生,而doSomething将在主主题上发生。

为了更进一步,您可以多次使用observeOn

myService.fetchSomeIntegersFromServer()
        .subscribeOn(Schedulers.newThread())
        .observeOn(Schedulers.computation())
        .filter(integer -> {
            System.out.println(Looper.getMainLooper().getThread() == Thread.currentThread());
            return true;
        })
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(integer1 -> { doSomething(integer1) });

在这种情况下,将在新线程上进行提取,在计算线程上进行过滤,并在主线程上进行doSomething

结帐ReactiveX - SubscribeOn operator获取官方文档。