RxAndroid和多线程

时间:2016-05-14 05:19:36

标签: 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函数?

1 个答案:

答案 0 :(得分:2)

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

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

对于您要实现的目标,我会使用Observable.defer来自docs

  

Defer运算符等待观察者订阅它,然后它生成一个Observable,通常具有Observable工厂函数。

代码看起来像:

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(),否则该线程将没有looper。你通常不需要在线程上使用looper,除非你想以任何方式发布Runnable