【问题标题】:Replace AsyncTask with Rxjava for Room Database将房间数据库的 AsyncTask 替换为 Rxjava
【发布时间】:2021-03-18 05:43:59
【问题描述】:

我正在尝试用 RxJava 替换 AsyncTask,因为 Async 在 Android 11 中已被弃用。但是我无法让 RxJava 与 Room 一起使用,

这是当前使用 Asynctask 的工作代码:

在存储库中:

public void insertItems(List<Items> items){
    new insertItemsAsyncTask(PrjDao).execute(items);
}

private static class insertItemAsyncTask extends AsyncTask<List<Items>, Void, Void>{
    private PrjDao prjDao;

    private insertItemAsyncTask(PrjDao prjDao){
        this.prjDao = prjDao;
    }

    @Override
    protected Void doInBackground(List<Items>... lists) {
        prjDao.insertItems(lists[0]);
        return null;
    }
}

在 DAO 中

@Insert
void insertItems(List<Items> items);

我将存储库代码替换为:

public void insertItems(List<Items> items){
    Completable.fromAction(() -> prjDao.insertItems(items)).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
            .subscribe(new CompletableObserver() {
                @Override
                public void onSubscribe(@NonNull Disposable d) {

                }

                @Override
                public void onComplete() {

                }

                @Override
                public void onError(@NonNull Throwable e) {

                }
            });
}

但是它不起作用,即使我设法在 onComplete 中获得日志输出。

【问题讨论】:

    标签: android android-asynctask rx-java android-room


    【解决方案1】:

    试试:

    道:

    @Insert
    Completable insertItems(List<Items> items);
    

    存储库:

    public void insertItems(List<Items> items){ 
        prjDao.insertItems(items))
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(...);
    }
    

    或者更好:

    存储库:

    public Completable insertItems(List<Items> items){ 
        return prjDao.insertItems(items))
    }
    

    然后,订阅可完成并处理您实际调用 insertItems() 的订阅回调。

    insertItems(items)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(...);
    

    在我看来,存储库应该只提供到数据库接口的桥梁,调用者应该是处理订阅回调的人,因为每个调用者可能希望以不同的方式处理回调。

    更新

    要在房间中使用 rxjava,请检查您的 build.gradle 文件中是否包含所有需要的依赖项:

    implementation "androidx.room:room-runtime:[roomVersion]"
    implementation "androidx.room:room-rxjava2:[roomVersion]"
    annotationProcessor "androidx.room:room-compiler:[roomVersion]"
    

    我目前使用 roomVersion 2.2.5

    这是我刚刚创建的 room + rxjava 的简单工作演示,也许你会发现那里的不同之处:

    https://github.com/phamtdat/RxRoomDemo

    【讨论】:

    • 感谢您的回复,我尝试了您的解决方案,它在 DAO 中给了我以下错误:错误:不确定如何处理插入方法的返回类型。可完成的 insertItems(List items);
    • 在我看来您可能缺少一些依赖项,请检查我更新的答案,看看是否有帮助。
    • 我缺少依赖项,但我仍然收到同样的问题:错误:不确定如何处理插入方法的返回类型。可完成的 insertItems(List items); ^[WARN] 请求增量注释处理,但支持被禁用,因为以下处理器不是增量的:androidx.room.RoomProcessor (DYNAMIC)。
    • 抱歉,kapt 仅适用于 kotlin。您正在使用 java,因此请尝试使用 annotationProcessor(请参阅我编辑的答案)。同时我会检查是否还有其他问题。
    • 很好的答案!我至少会在存储库中放置 .subscribeOn(Schedulers.io()) 以避免将来在主线程上调用 Room 查询时头疼,尤其是在处理长链操作时。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    • 1970-01-01
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多