领域,网络操作,使用RxJava订阅和观察不同的线程

时间:2016-01-14 22:28:12

标签: rx-java realm-list realm

我需要:

  • 从后台线程上的API中获取一些数据
  • 在UI上显示数据
  • 保存到领域。

    fetchItemsFromServer().subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<ItemList>() {
        @Override
        public void call(ItemList items) {
    
            displayItems(items);
    
            try {
                realm.beginTransaction();
                realm.copyToRealmOrUpdate(itemList);
                realm.commitTransaction();
                Logger.v("Realm ", "Copied list object to realm");
            } catch (Exception e) {
                Logger.e("Realm Something went wrong ", e);
                realm.cancelTransaction();
            }
    
        }
    }
    

这会引发错误: 从不正确的线程访问的域

我有4个标签同时提取不同的消息。

fetchItemsFromServer()是一个密集型调用,将此调用限制在一个线程中并不好。我需要这种灵活性。

有没有人发现任何使用领域的变通方法?

大多数例子往往侧重于从Realm获取和使用网络操作:

以下示例:

Rxjava - https://realm.io/news/realm-java-0.87.0/

将域与RxJava一起使用 - https://realm.io/news/using-realm-with-rxjava/(先前的解决方案,但性能缺点)

My Realm由数据库模块通过依赖注入(Dagger 2)提供

@Module
public class DatabaseModule {

    public static final String REALM_FILE_NAME = "Realm name";

    @Provides
    Realm providesRealmInstance(Context context) {
    return Realm.getInstance(
            new RealmConfiguration.Builder(context)
                    .name(REALM_FILE_NAME)
                    .build());
    }
}

1 个答案:

答案 0 :(得分:4)

不是在UI线程上保存数据,而是使用以下模式在后台执行:

fetchItemsFromServer()
    .doOnNext(new Action1<ItemList>() {
        @Override
        public ItemList call(ItemList list) {
            // Save data on the background thread
            Realm realm = Realm.getDefaultInstance();
            realm.beginTransaction();
            realm.copyToRealmOrUpdate(list);
            realm.commitTransaction();
            realm.close();
        }
    })
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(new Action1<ItemList>() {
    @Override
    public void call(ItemList items) {
        displayItems(items);
    }
}