初步了解JetPack中的Room(2)
本文为学习类文档,通过学习B站up主longway777的视频,再加上自己的总结与理解的学习类文章,如有侵权,请联系博主进行删除
初步了解JetPack中的Room(2)
在了解了Entity、Dao、Database后,继续引入AsyncTask、Repository、ViewModel、LiveData。
使用AsyncTask对Room的数据库操作转移至该线程中(不能放在主线程)
将数据库内容存入ViewModel中并引入LiveData
将数据库的各类操作放入抽象类Repository中
使用上次的项目
做修改:
- List数据改为LiveData<List<>>:
@Query("SELECT * FROM WORD ORDER BY ID DESC")
//List<Word> getAllWords();
LiveData<List<Word>>getAllWordsLive(); //更改返回值为LiveData类型
MainActivity.java中(添加变量,链接Dao接口函数,设置观察者以完成数据变动时自动更新):
package com.example.roombasic;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.List;
public class MainActivity extends AppCompatActivity {
WordDatabase wordDatabase;
WordDao wordDao;
TextView textView;
Button buttonInsert,buttonUpdate,buttonDelete,buttonClear;
//编辑变量保存LiveData
LiveData<List<Word>> allWordsLive;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取database对象需要一个函数databaseBuilder并创建
wordDatabase = Room.databaseBuilder(this,WordDatabase.class,"word_database")
.allowMainThreadQueries() //强制允许主线程执行,该方法不好,
.build();
wordDao = wordDatabase.getWordDao();
allWordsLive = wordDao.getAllWordsLive();
textView = findViewById(R.id.textView);
//LiveData观察变动呼叫onchange函数,完成界面自动刷新
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());
}
});
buttonInsert = findViewById(R.id.buttonInsert);
buttonClear = findViewById(R.id.buttonClear);
buttonDelete = findViewById(R.id.buttonDelete);
buttonUpdate = findViewById(R.id.buttonUpdate);
//插入
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);
//updateView();
}
});
//清空
buttonClear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
wordDao.deleteAllWords();
}
});
//删除
buttonDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Word word = new Word("",""); //删除只与id有关,内容无所谓
word.setId(1); //根据ID修改对应的表单名
wordDao.deleteWords(word);
}
});
//修改
buttonUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Word word = new Word("Android","安卓");
word.setId(1); //根据ID修改对应的表单名
wordDao.updateWords(word);
}
});
}
}
- Database变更为Singleton模式(单实例,database实例化比较耗费资源)
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
@Database(entities = {Word.class},version = 1,exportSchema = false) //三个参数分别为数据库中的表、数据库版本号和导出模式
public abstract class WordDatabase extends RoomDatabase {
//变更为Singleton模式
private static WordDatabase INSTANCE;
static synchronized WordDatabase getDatabase(Context context) { //synchronized避免碰撞冲突
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),WordDatabase.class,"word_database")
.allowMainThreadQueries()
.build();
}
return INSTANCE;
}
public abstract WordDao getWordDao(); //只需写一个函数原型即可
}
- 借助AsyncTask将数据库脱离主线程并放入正确的工作线程中:
AsyncTsak为抽象类,每个操作都要生成单独的子类
在MainActivity.java中添加代码
//内部类存在形式声明为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();
}
*/
}
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 ClearAsyncTask extends AsyncTask<Void,Void,Void> {
private WordDao wordDao;
public ClearAsyncTask(WordDao wordDao) {
this.wordDao = wordDao;
}
//重写函数
@Override
protected Void doInBackground(Void... voids) {
wordDao.deleteAllWords();
return null;
}
}
- 变动数据库操作按钮点击的响应事件,并删除主线程强制执行功能:
wordDao.insertWords(word1,word2);
变更为
new InsertAsyncTask(wordDao).execute(word1,word2);
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.List;
public class MainActivity extends AppCompatActivity {
WordDatabase wordDatabase;
WordDao wordDao;
TextView textView;
Button buttonInsert,buttonUpdate,buttonDelete,buttonClear;
//编辑变量保存LiveData
LiveData<List<Word>> allWordsLive;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取database对象需要一个函数databaseBuilder并创建
wordDatabase = Room.databaseBuilder(this,WordDatabase.class,"word_database")
.build();
wordDao = wordDatabase.getWordDao();
allWordsLive = wordDao.getAllWordsLive();
textView = findViewById(R.id.textView);
//LiveData观察变动呼叫onchange函数,完成界面自动刷新
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());
}
});
buttonInsert = findViewById(R.id.buttonInsert);
buttonClear = findViewById(R.id.buttonClear);
buttonDelete = findViewById(R.id.buttonDelete);
buttonUpdate = findViewById(R.id.buttonUpdate);
//插入
buttonInsert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Word word1 = new Word("Hello","你好");
Word word2 = new Word("World","世界");
new InsertAsyncTask(wordDao).execute(word1,word2); //创建线程操作并将创建的变量执行到父线程中操作,下同
}
});
//清空
buttonClear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new ClearAsyncTask(wordDao).execute();
}
});
//删除
buttonDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Word word = new Word("",""); //删除只与id有关,内容无所谓
word.setId(1); //根据ID修改对应的表单名
new DeleteAsyncTask(wordDao).execute(word);
}
});
//修改
buttonUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Word word = new Word("Android","安卓");
word.setId(1); //根据ID修改对应的表单名
new UpdateAsyncTask(wordDao).execute(word);
}
});
}
//内部类存在形式声明为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;
}
}
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 ClearAsyncTask extends AsyncTask<Void,Void,Void> {
private WordDao wordDao;
public ClearAsyncTask(WordDao wordDao) {
this.wordDao = wordDao;
}
//重写函数
@Override
protected Void doInBackground(Void... voids) {
wordDao.deleteAllWords();
return null;
}
}
}
将数据相关的代码存入ViewModel中(使用AndroidViewModel)
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.getAllWordsLive();
}
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 clearWords(Word...words) {
new ClearAsyncTask(wordDao).execute();
}
//内部类存在形式声明为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;
}
}
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 ClearAsyncTask extends AsyncTask<Void,Void,Void> {
private WordDao wordDao;
public ClearAsyncTask(WordDao wordDao) {
this.wordDao = wordDao;
}
//重写函数
@Override
protected Void doInBackground(Void... voids) {
wordDao.deleteAllWords();
return null;
}
}}
MainActivity.java精简后的代码:
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.List;
public class MainActivity extends AppCompatActivity {
WordDao wordDao;
TextView textView;
Button buttonInsert,buttonUpdate,buttonDelete,buttonClear;
WordViewModel wordViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wordViewModel = new ViewModelProvider(this).get(WordViewModel.class);
textView = findViewById(R.id.textView);
//LiveData观察变动呼叫onchange函数,完成界面自动刷新
wordViewModel.getAllWordsLive().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());
}
});
buttonInsert = findViewById(R.id.buttonInsert);
buttonClear = findViewById(R.id.buttonClear);
buttonDelete = findViewById(R.id.buttonDelete);
buttonUpdate = findViewById(R.id.buttonUpdate);
//插入
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);
}
});
//清空
buttonClear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
wordViewModel.clearWords();
}
});
//删除
buttonDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Word word = new Word("",""); //删除只与id有关,内容无所谓
word.setId(1); //根据ID修改对应的表单名
wordViewModel.deleteWords(word);
}
});
//修改
buttonUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Word word = new Word("Android","安卓");
word.setId(1); //根据ID修改对应的表单名
wordViewModel.deleteWords(word);
}
});
}
}
运行无问题
建立仓库类Repository将ViewModel中的数据直接操作的信息提取出来
WordRepository.java
package com.example.roombasic;
import android.content.Context;
import android.os.AsyncTask;
import androidx.lifecycle.LiveData;
import java.util.List;
public class WordRepository {
private LiveData<List<Word>> allWordsLive; //ViewModel中就不用保留变量了
private WordDao wordDao;
public WordRepository(Context context) {
WordDatabase wordDatabase = WordDatabase.getDatabase(context.getApplicationContext());
wordDao = wordDatabase.getWordDao();
allWordsLive = wordDao.getAllWordsLive();
}
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 clearWords(Word... words) {
new ClearAsyncTask(wordDao).execute();
}
public LiveData<List<Word>> getAllWordsLive() {
return allWordsLive;
}
//内部类存在形式声明为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;
}
}
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 ClearAsyncTask extends AsyncTask<Void,Void,Void> {
private WordDao wordDao;
public ClearAsyncTask(WordDao wordDao) {
this.wordDao = wordDao;
}
//重写函数
@Override
protected Void doInBackground(Void... voids) {
wordDao.deleteAllWords();
return null;
}
}
}
MainActivity.java中修改代码:
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import java.util.List;
public class WordViewModel extends AndroidViewModel {
private WordRepository wordRepository;
public WordViewModel(@NonNull Application application) {
super(application);
wordRepository = new WordRepository(application);
}
public LiveData<List<Word>> getAllWordsLive() {
return wordRepository.getAllWordsLive();
}
void insertWords(Word... words) {
wordRepository.insertWords(words);
}
void updateWords(Word... words) {
wordRepository.updateWords(words);
}
void deleteWords(Word... words) {
wordRepository.deleteWords(words);
}
void clearWords() {
wordRepository.clearWords();
}
}
运行无问题
小结
将上次的数据库做完善
- 引入LiveData
- 引入AsyncTask进行后台执行
- database类修改为singleton模式保证只有一个实例
- 引入ViewModel使controller中数据代码得到精简,并将数据代码的获取部分封装到Repository中