Realm结合RxJava改造CRUD:更新与删除操作实现疑问
用RxJava重构Realm的更新与删除操作
你的思路对吗?
首先,你的方向完全没问题——把Realm的CRUD操作Rx化,能更好地利用RxJava的线程调度、生命周期管理和错误处理能力。至于是否返回操作结果,其实看你的业务需求:
- 如果需要知道操作是否生效(比如删除是否找到对应数据、更新是否完成),可以返回结果(比如用
Boolean表示成功与否,或者返回受影响的行数); - 如果只是执行操作不关心结果,用
Completable(表示操作完成、无返回值)会更简洁,这也是Rx里处理无返回操作的标准做法。
你之前的删除代码出错,核心问题是flatMap的用法不对:flatMap要求传入的函数必须返回一个Flowable(或其他Rx流类型),但你直接返回了Boolean,而且deleteAllFromRealm()本身是void返回,这段代码本身就有语法问题。下面给你具体的改造方案:
正确改造删除操作
我们可以用Flowable.fromCallable来包裹Realm的事务操作,既能正确处理线程,也能灵活返回操作结果。同时要注意用try-with-resources管理Realm实例,避免内存泄漏:
返回删除结果(比如是否有数据被删除)
public <T extends RealmObject> Flowable<Boolean> deleteDataById(String publicId, Class<T> clazz) { return Flowable.fromCallable(() -> { try (Realm realm = Realm.getDefaultInstance()) { // 用executeTransactionCopy获取事务内的返回结果 return realm.executeTransactionCopy(r -> { RealmResults<T> results = r.where(clazz) .equalTo("publicId", publicId) .findAll(); boolean hasDeleted = !results.isEmpty(); results.deleteAllFromRealm(); return hasDeleted; }); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); }
仅关心操作完成(用Completable)
如果不需要知道删除结果,用Completable会更轻量:
public <T extends RealmObject> Completable deleteDataById(String publicId, Class<T> clazz) { return Completable.fromAction(() -> { try (Realm realm = Realm.getDefaultInstance()) { realm.executeTransaction(r -> { RealmResults<T> results = r.where(clazz) .equalTo("publicId", publicId) .findAll(); results.deleteAllFromRealm(); }); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); }
正确改造更新操作
同样用Rx流包裹事务操作,根据需求选择返回结果或仅执行操作:
返回更新后的对象(如果业务需要)
public <T extends RealmObject> Flowable<T> updateData(T object) { return Flowable.fromCallable(() -> { try (Realm realm = Realm.getDefaultInstance()) { return realm.executeTransactionCopy(r -> { r.insertOrUpdate(object); Log.d(LOG_TAG, "updateData"); // 返回分离后的对象,避免托管对象的线程限制 return r.copyFromRealm(object); }); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); }
仅关心操作完成(用Completable)
public <T extends RealmObject> Completable updateData(T object) { return Completable.fromAction(() -> { try (Realm realm = Realm.getDefaultInstance()) { realm.executeTransaction(r -> { Log.d(LOG_TAG, "updateData"); r.insertOrUpdate(object); }); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); }
额外注意点
- 线程调度:Realm的写操作必须在非UI线程执行,所以一定要用
subscribeOn(Schedulers.io())把操作放到IO线程; - Realm实例管理:始终用try-with-resources自动关闭Realm实例,避免内存泄漏;
- 泛型复用:保持方法的泛型化,像你之前的查询方法那样,不要局限于某个具体Model类,提升复用性;
- 事务选择:结合Rx使用时,用同步事务+Rx线程调度比
executeTransactionAsync更可控,能更好地整合Rx的生命周期和错误处理。
内容的提问来源于stack exchange,提问作者No Name
相关产品推荐
相关产品推荐

