Android JetPack学习总结(七)

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

发表评论