改造上一节 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() + "
");
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();
}
});
3. 引入 AndroidViewModel ,简化 MainActivity
package com.example.roombasic;
import android.app.Application;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import java.util.List;
public class WordViewModel extends AndroidViewModel {
private WordDao wordDao;
private LiveData<List<Word>> allWordsLive;
public WordViewModel(@NonNull Application application) {
super(application);
WordDatabase wordDatabase = WordDatabase.getDatabase(application);
wordDao = wordDatabase.getWordDao();
allWordsLive = wordDao.getAllWordLive();
}
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();
}
//内部类,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;
}
}
}
MainActivity.java
package com.example.roombasic;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.SavedStateViewModelFactory;
import androidx.lifecycle.ViewModelProvider;
import java.util.List;
public class MainActivity extends AppCompatActivity {
//WordDatabase wordDatabase;
//WordDao wordDao;
Button buttonInsert,buttonUpdate,buttonClear,buttonDelete;
TextView textView;
LiveData<List<Word>> allWordsLive;
WordViewModel wordViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//wordDatabase = Room.databaseBuilder(this,WordDatabase.class,"word_database")
//.allowMainThreadQueries() //allowMainThreadQueries() 强制允许在主线程运行
// .build();
//wordDao = wordDatabase.getWordDao();
//wordViewModel = ViewModelProviders
wordViewModel = new ViewModelProvider(this,new SavedStateViewModelFactory(getApplication(),this)).get(WordViewModel.class);
//allWordsLive = wordDao.getAllWordLive();
textView = findViewById(R.id.textView);
buttonInsert = findViewById(R.id.buttonInsert);
buttonUpdate = findViewById(R.id.buttonUpdate);
buttonClear = findViewById(R.id.buttonClear);
buttonDelete = findViewById(R.id.buttonDelete);
//利用 LiveData<> 与 observe的onChanged配合,数据自动刷新
//allWordsLive.observe(this, new Observer<List<Word>>() {
wordViewModel.getAllWordsLive().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() + "
");
textView.setText(text);
}
}
});
buttonInsert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Word word1 = new Word("Hello","你好");
Word word2 = new Word("World","世界");
wordViewModel.insertWords(word1,word2);
//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(68); //更新是用主键来更新的
wordViewModel.updateWords(word);
//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();
wordViewModel.deleteAllWords();
}
});
buttonDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Word word = new Word("English","英语");
word.setId(68); //删除也是用主键来更新的
wordViewModel.deleteWords(word);
//wordDao.deleteWords(word);
//new DeleteAsyncTask(wordDao).execute(word);
//updateView();
}
});
}
/*void updateView(){
List<Word> list = wordDao.getAllWords();
String text="";
textView.setText(text); //先将 textView 清空
for(int i=0;i<list.size();i++){
Word word = list.get(i);
text += word.getId() + ":" + word.getWord() + "=" + word.getChineseMeaning() + "
";
textView.setText(text);
}
}*/
}
4. 创建 仓库类,简化 ViewModel
package com.example.roombasic;
import android.content.Context;
import android.os.AsyncTask;
import androidx.lifecycle.LiveData;
import java.util.List;
public class WordRepository {
//数据仓库
private WordDao wordDao;
private LiveData<List<Word>> allWordsListLive;
public WordRepository(Context context) {
WordDatabase wordDatabase = WordDatabase.getDatabase(context.getApplicationContext());
wordDao = wordDatabase.getWordDao();
allWordsListLive = wordDao.getAllWordLive();
}
public LiveData<List<Word>> getAllWordsListLive() {
return allWordsListLive;
}
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();
}
//内部类,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;
}
}
}