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 ...
随机推荐
- MediaWiki上传文件大小设置
一.概述 MediaWiki默认最大上传文件大小为2M,碰到文件较大需要修改这个限制,需要改为8M. 二.修改php.ini 使用docker运行的MediaWiki,默认是没有php.ini这个文件 ...
- JavaIO学习:序列化流
对象流 1.涉及到的类 ObjectInputStream 和 ObjectOutputStream 用于存储和读取基本数据类型数据或对象的处理流. 2.作用 ObjectOutputStream:内 ...
- windows下生成ssl
1.安装git window 需要安装 git 按部就班即可 https://git-scm.com/ 2.安装完之后,打开 Git Bash 输入以下命令并执行,然后一路按“回车”即可,效果见图: ...
- Java Automic包下的AtomicInteger
感谢这两位博主的文章,文章源于: https://www.cnblogs.com/chenpi/p/5375805.html https://blog.csdn.net/fanrenxiang/art ...
- Golang fmt Printf 格式化参数手册/详解/说明
fmt 包实现了格式化I/O函数,类似于C的 printf 和 scanf. 格式“占位符”衍生自C,但比C更简单. fmt 包的官方文档对Printing和Scanning有很详细的说明.这里就直接 ...
- Form之action提交不刷新不跳转
<div class="file-box"> <form action="/File/fileUpLoad" id="form1&q ...
- python课程单元三编程题讲解(上)
目录 1.快乐的数字 2.凯撒密码I 3.凯撒密码II 4.括号配对检测 A @ 下面向大家介绍一下我在学习python课程的一些题目的解法,如果大家有什么更好的解法请私信我.这里只显示题目与 ...
- java内存溢出实战
通过设置-XX:+HeapDumpOnOutOfMemoryError 自动生成dump文件,进行分析内存溢出原因 1.堆溢出堆溢出原因莫过于对象太多导致. 错误:java.lang.OutOfMem ...
- codeforces #577(Div.2)
codeforces #577(Div.2) A Important Exam A class of students wrote a multiple-choice test. There are ...
- C#实现outlook自动签名
Outlook下实现自动签名的方式 网上找到一篇资料是在outlook里用vba实现的,但是这样实现的方式由于数字认证的问题不便于部署 在此介绍一种C#下实现的方式,目前确定的outlook版本为 ...