Android Studio 之 ROM【2】, LiveData+ViewModel+AsyncTask+Repository
改造上一节 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();
}
});
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;
}
}
}
Android Studio 之 ROM【2】, LiveData+ViewModel+AsyncTask+Repository的更多相关文章
- Android Studio 之 ROM【3】,LiveData+ViewModel+AsyncTask+Repository+RecyclerView
教程地址:https://www.bilibili.com/video/av65180549 源码地址:https://github.com/longway777/Android-2019-Tutor ...
- Android Studio 之 ROM【1】, Entity,Dao,Database
Android Studio 之 ROM, Entity,DAO,DataBase 1.Entity 实体类 package com.example.roombasic; import android ...
- How to distribute your own Android library through jCenter and Maven Central from Android Studio
In Android Studio, if you wish to include any library to your application. You could just simply add ...
- Android Studio 之 LiveData 的配合使用,底层数据变化,自动通知界面
Android Studio 之 LiveData 的配合使用,底层数据变化,自动通知界面 viewModelWithLikeData.getLikeNumber().observe(this, ne ...
- Android studio 分析内存泄漏
以前用eclipse的时候,我们采用的是DDMS和MAT,不仅使用步骤复杂繁琐,而且要手动排查内存泄漏的位置,操作起来比较麻烦.后来随着Android studio的潮流,我也抛弃了eclipse加入 ...
- Android 适配多种ROM的快捷方式
快捷方式 应该来说 很多人都做过,我们就来看一下基本的快捷方式 是怎么实现的,会有什么问题? 首先 肯定要获取权限: <!-- 添加快捷方式 --> <uses-permission ...
- [App]Android Studio First App
准备着看Android Studio的体验如何. 通过Android Studio构建一个默认的项目,添加一些元素 <RelativeLayout xmlns:android="htt ...
- Ubuntu 14.04 64位安装Android Studio 和 genymotion (下)
接上一篇,上回书说到,我们可以进android studio的编辑器了.感觉不错.挺好的,先不说genymotion,先看看你的android项目有没有r文件,项目有没有错误? 如果没有问题的话,下面 ...
- linux安装安卓开发工具android studio
http://www.android-studio.org/ http://android-studio.org/index.php/docs/guide 最近要接触android编程,本来想装ecl ...
随机推荐
- THUSC2019去不了记
因为泥萌都去SC了,就我在学校里考水考模拟,所以这就变成了水考模拟游记了 Day1 早上本来要到教室早读,发现教室被由年级前\(100\)的非竞赛生的dalao给占据了,发现聪聪在里面,于是进去愉快的 ...
- MongoDB 学习笔记 ---创建用户
MongoDB安装好了之后,开始学习常用命令 首先,运行MongoDB, 记住,先不用带参数--auth /usr/local/mongodb/bin/mongod -dbpath=/usr/loca ...
- 《 .NET并发编程实战》阅读指南 - 第2章
先发表生成URL以印在书里面.等书籍正式出版销售后会公开内容.
- SpringCloud 别人的主页
https://www.cnblogs.com/xuwujing/ java(28) springBoot(14) 设计模式(14) springcloud(7) hadoop(7) hive(5) ...
- C# LDAP认证登录类参考
public class LDAPHelper { private DirectoryEntry _objDirectoryEntry; /// <sum ...
- jQuery实现C#CheckBoxList模糊搜索
前言 最近开发的一套系统中需要对商品进行管理,在选择商品时,要分别从品牌.型号.商品三个类别分别选择对应的选项才能找到需要的商品,三者的关系为:品牌包含型号,型号包含商品,因此使用了三个不同的 asp ...
- C# vb .NET读取识别条形码线性条码gs1128
gs1-128,ean-128是比较常见的条形码编码规则类型的一种.如何在C#,vb等.NET平台语言里实现快速准确读取该类型条形码呢?答案是使用SharpBarcode! SharpBarcode是 ...
- 49道spring面试题整理,附带答案
1.选择使用Spring框架的原因? 使用Spring: 第一是使用它的IOC功能,在解耦上达到了配置级别. 第二是使用它对数据库访问事务相关的封装. 第三就是各种其他组件与Spring的融合,在Sp ...
- 离散数学交并补运算、差运算、异或运算的实现--biaobiao88
对集合的交并补运算.差运算及异或运算的代码,可输入字符与数字,内容简单,详情请看以下代码 #include<iostream> using namespace std; int main( ...
- Struts2处理(jQuery)Ajax请求
1. Ajax Ajax(Asynchronous JavaScript and XML,异步JavaScript和XML)时一种创建交互式网页应用的网页开发技术,它并不是一项新的技术,其产生 ...