android:使用 CompletableFuture 从 Room 加载列表? [英] android: load List from Room using CompletableFuture?

查看:77
本文介绍了android:使用 CompletableFuture 从 Room 加载列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于 AsyncTask() 方法已被弃用,我正在尝试替换它.以前 AsyncTask() 用于将 CardView 从 Room 数据库加载到 RecyclerView 列表中.我正在尝试使用 CompletableFuture() 作为替代,但该列表未加载.List getAllCards()"的 Dao 方法;在 Android Studio 中给出错误消息从未使用过该方法的返回值";所以听起来列表从未从数据库中获得.Repository 从 ViewModel 中获取 List 方法,ViewModel 在 MainActivity 中获取 List 方法调用.

Since AsyncTask() method is deprecated, I am trying to replace it. Previously AsyncTask() was used to load CardViews into a RecyclerView list from a Room database. I am trying to use CompletableFuture() as a replacement but the list does not load. The Dao method for "List getAllCards()" is giving an error message in Android Studio "Return value of the method is never used" so it sounds like the list is never obtained from the the database. The Repository gets the List method from the ViewModel and the ViewModel gets the List method call in the MainActivity.

我也想避免ExecutorService.submit(() - > cardDao()).get()";加载列表,因为它正在阻塞.我在下面展示了运行良好的 ExecutorService submit(() 方法,以供参考.

I also want to avoid "ExecutorService.submit(() - > cardDao()).get()" to load the list, since it is blocking. I show below the ExecutorService submit(() method that was working fine, for reference.

由于列表未加载,我在这里遗漏了什么?

What am I missing here since the list is not loading?

Repository

public List<Card> getAllCards() {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

        CompletableFuture.supplyAsync(() -> {
            List<Card> loadAllCards = new ArrayList<>();
            cardDao.getAllCards();
            return loadAllCards;
        }).thenAcceptAsync(loadAllCards -> getAllCards());
    }
    return null;
}

Dao

@Dao
public interface QuickcardDao {

    @Query("SELECT * FROM cards ORDER BY Sortorder DESC")
    List<Card> getAllCards();
} 

这是我要替换的存储库中的 AsyncTask():

Here is the AsyncTask() in the Repository that I am trying to replace:

public CardRepository(Application application) {
    CardRoomDatabase db = CardRoomDatabase.getDatabase(application);
    cardDao = db.cardDao();
}

public List<Card> getAllCards() {
    try {
        return new AllCardsAsyncTask(cardDao).execute().get();
    } catch (ExecutionException | InterruptedException e) {
        e.printStackTrace();
    }
    return null;
}

// AsyncTask for reading an existing CardViews from the Room database.
private static class AllCardsAsyncTask extends AsyncTask<Void, Void, List<Card>> {

    private CardDao cardDao;

    AllCardsAsyncTask(CardDao dao) {
        cardDao = dao;
    }

    @Override
    public List<Card> doInBackground(Void... voids) {

        return cardDao.getAllCards();
    }
}

这是我要替换的存储库中的 submit(() 方法:

Here is the submit(() method in the Repository that I am trying to replace:

public List<Card> getAllCards() {

    List<Card> newAllCards = null;
    try {
        newAllCards = CardRoomDatabase.databaseExecutor.submit(() -> cardDao.getAllCards()).get();
    }
    catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
    return newAllCards;
}

//结束

推荐答案

既然你说你不想使用 RxJavacoroutines 而我不熟悉 CompletableFuture 我想建议你从数据库中获取数据而不阻塞 UI 线程 的最简单方法 - 使用 LiveData.LiveData 默认在一个单独的线程上执行 fetch 操作,然后通知所有的观察者.

Since you said that you don't want to use neither RxJava or coroutines and i'm not familiar with CompletableFuture i wanna suggest you the easiest way to fetch data from database without blocking UI thread - using LiveData. LiveData performs fetch operation on a sepfrate thread by default and then notifies all the observers.

以下是必要的步骤:

  1. 将此依赖项添加到 gradle

  1. Add this dependency to gradle

实现androidx.lifecycle:lifecycle-livedata:2.3.1"

去掉所有与 Asynctask 或 CompletableFuture 相关的代码

Get rid of all code related with Asynctask or CompletableFuture


  1. 在你的@Dao注解类中添加如下方法

 @Dao
 public interface QuickcardDao {

 @Query("SELECT * FROM cards ORDER BY Sortorder DESC")
 LiveData<List<Card>> getAllCards();}


  1. 将方法添加到您的 Repo 中,如下所示

  1. Add method to your Repo as follows

public LiveData<List<Card>> getAllCards() {
        return cardDao.getAllCards();   
     }


  1. 向您的 ViewModel 添加方法,如下所示:

  1. Add method to your ViewModel as follows:

public LiveData>getAllCardsLive{ 返回 repo.getAllCards();}


  1. 在您的 Activity 中观察 LiveData

`viewModel.getAllCardsLive().observe(getViewLifeycleOwner(), cards ->{
     // submit obtained cards lit to your adapter
 }`

这篇关于android:使用 CompletableFuture 从 Room 加载列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆