将房间数据库的 AsyncTask 替换为 Rxjava

Posted

技术标签:

【中文标题】将房间数据库的 AsyncTask 替换为 Rxjava【英文标题】:Replace AsyncTask with Rxjava for Room Database 【发布时间】: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 中获得日志输出。

【问题讨论】:

【参考方案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 查询时头疼,尤其是在处理长链操作时。

以上是关于将房间数据库的 AsyncTask 替换为 Rxjava的主要内容,如果未能解决你的问题,请参考以下文章

如何解决替换 AsyncTask 以连接套接字的问题?

text RxJ使运营商扁平化

在这种情况下如何用 RxJava 替换 AsyncTask

用 Asynctask 更新 FragmentTransaction 替换的片段

替换现有项目中的 Asynctask 无需太多代码更改

如何使用 Runnable 回调替换 AsyncTask onProgressUpdate()