改造上一节 ROM【1】,
1.利用 LiveData<List<Word>> 与 observe 中的 onChanged 配合,删除掉之前的textView更新函数(updateTextView)
引入 LiveData 与 observe ,只要数据发生改变,就会自动更新内容。
Database 单例模式,因为Database实例化,会消耗大量资源,所以整个过程只实例化一个对象
package com.example.roombasic;
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
//抽象类
//singleton //单例模式,只允许实例化一个对象, Database 实例化很耗资源
@Database(entities = {Word.class},version = 1,exportSchema = false) //如果有多个实体,再加上逗号后加实体.Class,这里版本比较重要,每次更新都要改变
public abstract class WordDatabase extends RoomDatabase {
private static WordDatabase INSTANCE;
static WordDatabase getDatabase(Context context){
if(INSTANCE == null) {
//context.getApplicationContext() 获取当前Activity 的唯一的 Context
INSTANCE = Room.databaseBuilder(context.getApplicationContext(), WordDatabase.class, "word_database")
//.allowMainThreadQueries() 强制允许主线程操作
.build();
}
return INSTANCE;
}
public abstract WordDao getWordDao();
}
MainActity类中的代码:
LiveData<List<Word>> allWordsLive;
allWordsLive = wordDao.getAllWordLive();
//利用 LiveData<> 与 observe的onChanged配合,数据自动刷新
allWordsLive.observe(this, new Observer<List<Word>>() {
@Override
public void onChanged(List<Word> words) {
//当数据改变时会自动呼叫这个函数
//String text="";
StringBuilder text = new StringBuilder();
textView.setText(text); //先将 textView 清空
for(int i=0;i<words.size();i++){
Word word = words.get(i);
text.append(word.getId() + ":" + word.getWord() + "=" + word.getChineseMeaning() + "\n");
textView.setText(text);
}
}
});
WordDao类 中将数据返回类型改成 LiveData<List<Word>> 类型
@Query("SELECT * FROM WORD ORDER BY ID DESC")
LiveData<List<Word>> getAllWordLive();
2.引入 AsyncTask,用子线程更新数据
wordDatabase = Room.databaseBuilder(this,WordDatabase.class,"word_database")
//.allowMainThreadQueries() //allowMainThreadQueries() 强制允许在主线程运行
.build();
注释掉 allowMainThreadQueries()
在 MainActivity 中 添加内部类
//内部类,AsyncTask 类型的类 如果以内部类形式出现,必须用 static,否则告警,说内存泄漏
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;
}
/*@Override
protected void onPostExecute(Void aVoid) {
//任务完成时会呼叫,将结果带回给主线程
super.onPostExecute(aVoid);
}
@Override
protected void onProgressUpdate(Void... values) {
//当进度发生更新时,会呼叫
super.onProgressUpdate(values);
}
@Override
protected void onPreExecute() {
//在后台任务执行之前会呼叫
super.onPreExecute();
}*/
}
//内部类,AsyncTask 类型的类 如果以内部类形式出现,必须用 static,否则告警,说内存泄漏
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;
}
}
//内部类,AsyncTask 类型的类 如果以内部类形式出现,必须用 static,否则告警,说内存泄漏
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;
}
}
//内部类,AsyncTask 类型的类 如果以内部类形式出现,必须用 static,否则告警,说内存泄漏
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;
}
}
原来的4个操作方法中,注释掉主线程操作,改成由子线程操作数据
buttonInsert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Word word1 = new Word("Hello","你好");
Word word2 = new Word("World","世界");
//wordDao.insertWords(word1,word2); //这里是主线程直接插入数据
new InsertAsyncTask(wordDao).execute(word1,word2); //改成子线程对父线程插入数据
//updateView();
}
});
buttonUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Word word = new Word("English","英语");
word.setId(46); //更新是用主键来更新的
//wordDao.updateWords(word); //主线程操作
new UpdateAsyncTask(wordDao).execute(word); //子线程操作
//updateView();
}
});
//删除所有的记录
buttonClear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//wordDao.deleteAllWords(); //主线程操作
new DeleteAllAsyncTask(wordDao).execute();//由子线程来操作
//updateView();
}
});
buttonDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Word word = new Word("English","英语");
word.setId(46); //删除也是用主键来更新的
//wordDao.deleteWords(word); 主线程操作
new DeleteAsyncTask(wordDao).execute(word); //子线程操作
//updateView();
}
});
Android Studio 之 ROM【2】, LiveData+ViewModel+AsyncTask+Repository