java - RxAndroid 和多线程

标签 java android multithreading rx-java rx-android

我正在使用 RxAndroid 在后台做一些事情。这是我的代码:

Observable<MyClass[]> observable = Observable.create(new Observable.OnSubscribe<MyClass[]>() {

        @Override
        public void call(Subscriber<? super MyClass[]> subscriber) {
                System.out.println(Looper.myLooper() + " - " + Looper.getMainLooper());
                try {
                    MyObject myObject = ...
                    //do the background work
                    subscriber.onNext(myObject);
                    subscriber.onCompleted();
                } catch (Exception e) {
                    subscriber.onError(e);
                    e.printStackTrace();
                }
            }
        });

        observable.subscribeOn(Schedulers.newThread())
                  .observeOn(AndroidSchedulers.mainThread())
                  .subscribe(new Action1<MyClass[]>() {
                      @Override
                      public void call(MyClass[] myObjects) {
                          //do work on the ui Thread
                      }
                  }
        );

这是我第一次使用RxAndroid/RxJava/Looper.myLooper()/Looper.getMainLooper()

据我所知,Looper.myLooper() 为您提供当前代码正在运行的线程的名称 ID,Looper.getMainLooper() 为您提供主线程的ID。当我运行该应用程序时,在 SysOut 中,它会为它们打印出相同的 id。

我做错了什么还是我误解了2个Looper函数?

最佳答案

建议您不要使用Observable.create,除非您真的知道自己在使用 Observables 做什么。有很多事情你可能会出错。

创建中的代码在主线程上运行的原因是,它是在创建 Observable 时调用的,而不是在您订阅它时调用。

对于您想要实现的目标,我将使用 docs 中的 Observable.defer :

The Defer operator waits until an observer subscribes to it, and then it generates an Observable, typically with an Observable factory function.

代码看起来像:

Observable<MyObject> observable = Observable.defer(new Func0<Observable<MyObject>>() {
    @Override
    public Observable<MyObject> call() {

        System.out.println(Looper.myLooper() + " - " + Looper.getMainLooper());

        try {
            MyObject myObject = new MyObject();
            return Observable.just(myObject);
        }
        catch (Exception e) {
            return Observable.error(e);
        }

    }
});

Subscription s = observable
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
                new Action1<MyObject>() {
                    @Override
                    public void call(MyObject myObject) {

                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        throwable.printStackTrace();
                    }
                }
        );

现在在你的 logcat 中你将得到:

I/System.out: null - Looper (main, tid 1) {5282c4e0}

Looper.myLooper() 函数返回 null 的原因是,当您创建新线程时,除非调用 Looper.prepare(),否则该线程不会有活套。通常,线程上不需要循环程序,除非您无论如何都想向其发送 Runnable

关于java - RxAndroid 和多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37222875/

相关文章:

c# - 使用 TransactionScope 使常规(非数据库相关)C# 代码超时

c++ - itk 3.20.1 处理器亲和性

java - 如何同步添加元素和从队列中删除元素

java - 通过 cmd 提示符从 PHP 执行 .jar 文件并捕获输出

android - 如何在 Kotlin 中使用 anko 删除除最新 10 条记录之外的所有记录?

android - Material 设计 - ListView 中图标的正确大小是多少?

java - 如何使用 Retrofit 解析嵌套 json?

java - JUnit Spring with xml No Annotation 加载bean失败

java - Guava - 如何根据谓词从列表中删除,跟踪删除的内容?

java - 纪元或 Unix 时间 - Long.MAX_VALUE 人​​类可读日期