Room(二)

改善上一次的例子。(AsyncTask,LiveData,ViewModel,Repository)
使用LiveData来更新ui
在Dao中原来有
@Query("SELECT * FROM WORD ORDER BY ID desc")
    List<Word> getAllWords();方法,现将其修改为
@Query("SELECT * FROM WORD ORDER BY ID desc")
    LiveData<List<Word>> getAllWordsLive();这样就可以使用LiveData的Observer来动态更新界面,而不需要每一次都调用updateView方法:
//MainActivity
        allWordsLive=wordDao.getAllWordsLive();
        allWordsLive.observe(this, new Observer<List<Word>>() {
            @Override
            public void onChanged(List<Word> words) {
                StringBuilder text= new StringBuilder();
                for (int i=0;i<words.size();i++){
                    Word word=words.get(i);
                    text.append(word.getId()).append(": ").append(word.getWord()).append("= ").append(word.getChineseMeaning()).append("\n");
                }
                textView.setText(text.toString());
            }
        });
       用单例模式创建数据库连接
//WordDatabase
@Database(entities = {Word.class},version = 1,exportSchema =false)
public abstract class WordDatabase extends RoomDatabase {
    private static WordDatabase instance;
    public static synchronized WordDatabase getDatabase(Context context){
        if (instance==null){
            instance= Room.databaseBuilder(context.getApplicationContext(),
                    WordDatabase.class,"word_database")
                    .allowMainThreadQueries()
                    .build();
        }
        return instance;
    }
    public abstract WordDao getWordDao();
}在activity中调用:
wordDatabase= WordDatabase.getDatabase(this);用工作线程(AsyncTask)来完成数据库的访问
创建四个AsyncTask类:
static class InsertAsyncTask extends AsyncTask<Word,Void,Void>{
        private WordDao wordDao;
        public InsertAsyncTask(WordDao wordDao) {
            this.wordDao = wordDao;
        }
        @Override
        protected Void doInBackground(Word... words) {
            wordDao.insertWords(words);
            return null;
        }
    }
    static class UpdateAsyncTask extends AsyncTask<Word,Void,Void>{
        private WordDao wordDao;
        public UpdateAsyncTask(WordDao wordDao) {
            this.wordDao = wordDao;
        }
        @Override
        protected Void doInBackground(Word... words) {
            wordDao.updateWords(words);
            return null;
        }
    }
    static class DeleteAsyncTask extends AsyncTask<Word,Void,Void>{
        private WordDao wordDao;
        public DeleteAsyncTask(WordDao wordDao) {
            this.wordDao = wordDao;
        }
        @Override
        protected Void doInBackground(Word... words) {
            wordDao.deleteWords(words);
            return null;
        }
    }
    static class DeleteAllAsyncTask extends AsyncTask<Void,Void,Void>{
        private WordDao wordDao;
        public DeleteAllAsyncTask(WordDao wordDao) {
            this.wordDao = wordDao;
        }
        @Override
        protected Void doInBackground(Void... voids) {
            wordDao.deleteAllWords();
            return null;
        }
    }此后所有的数据库操作都通过AsyncTask类来操作。
添加ViewModel
创建viewModel以管理Dao和wordList,并且将数据库访问的AsyncTask类及其操作移动至该viewModel中。这样在activity中只需要通过viewModel来进行数据库访问。
public class WordViewModel extends AndroidViewModel {
    private WordDao wordDao;
    private LiveData<List<Word>> allWordsLive;
    public WordViewModel(@NonNull Application application) {
        super(application);
        WordDatabase wordDatabase= WordDatabase.getDatabase(getApplication());
        wordDao=wordDatabase.getWordDao();
        allWordsLive=wordDao.getAllWordsLive();
    }
    public WordDao getWordDao() {
        return wordDao;
    }
    public LiveData<List<Word>> getAllWordsLive() {
        return allWordsLive;
    }
    void insertWords(Word... words){
        new InsertAsyncTask(wordDao).execute(words);
    }
    void updateWords(Word... words){
        new UpdateAsyncTask(wordDao).execute(words);
    }
    void deleteWords(Word... words){
        new DeleteAsyncTask(wordDao).execute(words);
    }
    void deleteAllWords(Word... words){
        new DeleteAllAsyncTask(wordDao).execute();
    }
    static class InsertAsyncTask extends AsyncTask<Word,Void,Void> {
    }
    static class UpdateAsyncTask extends AsyncTask<Word,Void,Void>{
    }
    static class DeleteAsyncTask extends AsyncTask<Word,Void,Void>{
    }
    static class DeleteAllAsyncTask extends AsyncTask<Void,Void,Void>{
}创建Repository来获取和存储数据
viewModel是用于管理界面的数据,然而数据的获取不应该放在viewModel中。现在应该创建仓库类来进行中介,让viewModel通过仓库类来获取和存储。
将数据库操作的四个AsyncTask类移动到WordRepository,将对数据操作的四个方法也移动到repository中。
public class WordRepository {
    private LiveData<List<Word>> allWordsLive;
    private WordDao wordDao;
    public WordRepository(Context context) {
        WordDatabase wordDatabase= WordDatabase.getDatabase(context);
        wordDao=wordDatabase.getWordDao();
        allWordsLive=wordDao.getAllWordsLive();
    }
    public LiveData<List<Word>> getAllWordsLive() {
        return allWordsLive;
    }
    public void insertWords(Word... words){
        new InsertAsyncTask(wordDao).execute(words);
    }
    public void updateWords(Word... words){
        new UpdateAsyncTask(wordDao).execute(words);
    }
    public void deleteWords(Word... words){
        new DeleteAsyncTask(wordDao).execute(words);
    }
    public void deleteAllWords(Word... words){
        new DeleteAllAsyncTask(wordDao).execute();
    }
    static class InsertAsyncTask extends AsyncTask<Word,Void,Void> {
        private WordDao wordDao;
        public InsertAsyncTask(WordDao wordDao) {
            this.wordDao = wordDao;
        }
        @Override
        protected Void doInBackground(Word... words) {
            wordDao.insertWords(words);
            return null;
        }
    }
    static class UpdateAsyncTask extends AsyncTask<Word,Void,Void>{
        private WordDao wordDao;
        public UpdateAsyncTask(WordDao wordDao) {
            this.wordDao = wordDao;
        }
        @Override
        protected Void doInBackground(Word... words) {
            wordDao.updateWords(words);
            return null;
        }
    }
    static class DeleteAsyncTask extends AsyncTask<Word,Void,Void>{
        private WordDao wordDao;
        public DeleteAsyncTask(WordDao wordDao) {
            this.wordDao = wordDao;
        }
        @Override
        protected Void doInBackground(Word... words) {
            wordDao.deleteWords(words);
            return null;
        }
    }
    static class DeleteAllAsyncTask extends AsyncTask<Void,Void,Void>{
        private WordDao wordDao;
        public DeleteAllAsyncTask(WordDao wordDao) {
            this.wordDao = wordDao;
        }
        @Override
        protected Void doInBackground(Void... voids) {
            wordDao.deleteAllWords();
            return null;
        }
    }
}
在ViewModel中仍需要保留对数据操作的方法,只不过所有的操作都是调用repository中的方法来进行。
void insertWords(Word... words){
        wordRepository.insertWords(words);
    }
    void updateWords(Word... words){
        wordRepository.updateWords(words);
    }
    void deleteWords(Word... words){
        wordRepository.deleteWords(words);
    }
    void deleteAllWords(){
        wordRepository.deleteAllWords();
    }