问题描述
由于 AsyncTask() 方法已被弃用,我正在尝试替换它。以前 AsyncTask() 用于将 CardView 从 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;
}
// 结束
解决方法
既然你说你不想使用 RxJava
或 coroutines
并且我不熟悉 CompletableFuture
我想建议你从数据库中获取数据的最简单方法不阻塞 UI thread
- 使用 LiveData
。 LiveData
默认在单独的线程上执行 fetch 操作,然后通知所有观察者。
以下是必要的步骤:
-
将此依赖项添加到 gradle
implementation "androidx.lifecycle:lifecycle-livedata:2.3.1"
-
去掉所有与 Asynctask 或 CompletableFuture 相关的代码
-
将如下方法添加到您的
@Dao
注释类@Dao public interface QuickcardDao { @Query("SELECT * FROM cards ORDER BY Sortorder DESC") LiveData<List<Card>> getAllCards();}
-
将方法添加到您的 Repo 中,如下所示
public LiveData<List<Card>> getAllCards() { return cardDao.getAllCards(); }
-
向您的 ViewModel 添加方法,如下所示:
public LiveData<List<Card>> getAllCardsLive{ return repo.getAllCards(); }
-
在您的活动中观察
LiveData
`viewModel.getAllCardsLive().observe(getViewLifeycleOwner(),cards ->{ // submit obtained cards lit to your adapter }`