2016-12-28 76 views
1

我有一个持有对我的数据库对象的引用的单例。我想要做的是将任何数据库操作限制为单个IO线程。RxJava(Android) - 保持调度程序是否有任何伤害?

首先,我试着用以下几点:

class SQLSingleton{ 

... 

public Observable<MyObject> query(final String id){ 

    return Observable.fromCallable(() -> { 

     //database operations here 
    }) 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()); 
} 

... 
} 

这种方法的问题是,Schedulers.io()可能会从池中订阅了我上面的观察到的每个用户赋予不同的线程(和我不希望这样,我希望代码在任何时候都在同一个线程上执行)。

我然后转移到拿着调度自己的办法:

class SQLSingleton{ 

private final Scheduler schedulerIODatabase; 

public SQLSingleton(){ 
     schedulerIODatabase = Schedulers.newThread(); 
} 

public Observable<MyObject> query(final String id){ 

    return Observable.fromCallable(() -> { 

     //database operations here 
    }) 
    .subscribeOn(schedulerIODatabase) 
    .observeOn(AndroidSchedulers.mainThread()); 
} 

... 
} 

由于我是新来RxJava(和它看起来像它有很多缺陷的),我问:有什么危害在保持该调度对象活着(请记住,SQLSingleton是一个单身,因此该调度也将)?

回答

3

schedulerIODatabase = Schedulers.newThread();

,没有任何效果,因为每次与subscribeOn应用时,类似io()但没有线程重用newThread手了一个新的线程。

您不能在RxJava 1.x中固定和重新使用特定的RxJava线程,但可以在RxJava 2中使用其扩展库组件:SharedScheduler

在RxJava 1中,您必须提供您自己的单线程ExecutorServiceSchedulers.from,然后将使用该单个Executor进行所有工作调用。请注意,您必须手动管理ExecutorService的生命周期,并在应用程序必须终止时关闭它:

ExecutorService exec = Executors.newSingleThreadedExecutor(); 

Scheduler singleScheduler = Schedulers.from(exec); 

Observable.fromCallable(() -> { 
    //database operations here 
}) 
.subscribeOn(singleScheduler) 
.observeOn(AndroidSchedulers.mainThread()); 

// ... 

exec.shutdown(); 
+0

感谢您对@akarnokd提出的宝贵意见。您能否澄清一下我将如何“手动管理您的ExecutorService的生命周期并在应用程序终止时关闭它”?我应该在我的应用程序对象的onDestroy方法上做到这一点?我的印象是,我不必关心这些东西,因为这些对象是单身人士,因此如果应用程序关闭,它们将被正确“收集”。 – Tiago

+0

我不知道Android是否自动关闭ExecutorServices,它肯定不会在桌面Java应用程序中发生。 onCreate/onDestroy对听起来很合理。 – akarnokd