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