繁体   English   中英

android:使用 CompletableFuture 从 Room 加载列表?

[英]android: load List from Room using CompletableFuture?

由于不推荐使用 AsyncTask() 方法,因此我正在尝试替换它。 以前 AsyncTask() 用于将 CardViews 从 Room 数据库加载到 RecyclerView 列表中。 我正在尝试使用 CompletableFuture() 作为替代,但列表未加载。 “List getAllCards()”的 Dao 方法在 Android Studio 中给出错误消息“从不使用该方法的返回值”,因此听起来该列表从未从数据库中获取。 Repository 从 ViewModel 中获取 List 方法,ViewModel 在 MainActivity 中获取 List 方法调用。

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

由于列表未加载,我在这里缺少什么?

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() :

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(() 方法:

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 thread - 使用LiveData LiveData默认在单独的线程上执行 fetch 操作,然后通知所有观察者。

以下是必要的步骤:

  1. 将此依赖项添加到 gradle

    implementation "androidx.lifecycle:lifecycle-livedata:2.3.1"

  2. 摆脱所有与 Asynctask 或 CompletableFuture 相关的代码


  1. 将如下方法添加到您的@Dao注释 class

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

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

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

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

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


  1. 在 Activity 中观察LiveData

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM