改造上一節 ROM【1】,java
1.利用 LiveData<List<Word>> 與 observe 中的 onChanged 配合,刪除掉以前的textView更新函數(updateTextView)android
引入 LiveData 與 observe ,只要數據發生改變,就會自動更新內容。app
Database 單例模式,由於Database實例化,會消耗大量資源,因此整個過程只實例化一個對象ide
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>> 類型ui
@Query("SELECT * FROM WORD ORDER BY ID DESC")
LiveData<List<Word>> getAllWordLive();
2.引入 AsyncTask,用子線程更新數據 this
wordDatabase = Room.databaseBuilder(this,WordDatabase.class,"word_database")
//.allowMainThreadQueries() //allowMainThreadQueries() 強制容許在主線程運行
.build();
註釋掉 allowMainThreadQueries()spa
在 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個操做方法中,註釋掉主線程操做,改爲由子線程操做數據server
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() + "\n");
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() + "\n";
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;
}
}
}