zoukankan      html  css  js  c++  java
  • 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() + "
    ");
    
                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;
            }
        }
    }
    

      

  • 相关阅读:
    HDU 4632 CF 245H 区间DP(回文)
    Cloud Foundry中 JasperReports service集成
    Graphs and Minimum Cuts(Karger's Min-Cut Algorithm)
    【大盛】HTC one/M7 ROM 最新本地化OrDroid8.2.6 高级、快速设置 永久root 更多自定义 稳定 流畅
    Android开发工具GenyMotion安装和使用方法
    CF 121E Lucky Array 【树状数组】
    [每日一题] OCP1z0-047 :2013-08-02 权限―――分配系统权限
    iOS 应用程序本地化
    Storm系列(十五)架构分析之Executor-Spout
    Ganglia系列(一)安装
  • 原文地址:https://www.cnblogs.com/gfwei/p/11808966.html
Copyright © 2011-2022 走看看