Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.2k views
in Technique[技术] by (71.8m points)

android: load List from Room using CompletableFuture?

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.

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();
} 

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();
    }
}

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;
}

// End

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

Here are necessary steps:

  1. Add this dependency to gradle

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

  2. Get rid of all code related with Asynctask or CompletableFuture


  1. Add method as follows to your @Dao annotated class

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

  1. Add method to your Repo as follows

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

  1. Add method to your ViewModel as follows:

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


  1. Observe LiveData in your Activity

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...