600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > Android学习笔记 93. Room LiveData 和 ViewModel

Android学习笔记 93. Room LiveData 和 ViewModel

时间:2022-05-11 23:27:38

相关推荐

Android学习笔记 93. Room LiveData 和 ViewModel

Android学习笔记

Android 开发者基础知识 (Java) —— Google Developers 培训团队

文章目录

Android学习笔记Android 开发者基础知识 (Java) —— Google Developers 培训团队第3单元 在后台运行第10课 使用Room存储数据93. Room、LiveData 和 ViewModel93.1 创建项目93.2 创建Word实体93.3 创建DAO93.4 使用LiveData93.5 添加Room数据库93.6 创建存储库93.7 创建ViewModel93.8 为UI添加XML布局93.9 创建一个Adapter并添加RecylerView93.10 填充数据库93.11 将UI与数据连接起来93.12 创建一个用于添加单词的Activity93.13 小结

第3单元 在后台运行

第10课 使用Room存储数据

93. Room、LiveData 和 ViewModel

项目地址:/google-developer-training/android-fundamentals-apps-v2/tree/master/RoomWordsSample

93.1 创建项目
创建项目更新Gradle配置文件
93.2 创建Word实体

表结构

创建Word类

public class Word {private String mWord;public Word(@NonNull String word) {this.mWord = word;}public String getWord(){return this.mWord;}}

注解Word类

@Entity(tableName = "word_table")public class Word {@PrimaryKey@NonNull@ColumnInfo(name = "word")private String mWord;public Word(@NonNull String word) {this.mWord = word;}public String getWord(){return this.mWord;}}

93.3 创建DAO

数据访问对象或Dao是一个带注释的类,您可以在其中指定 SQL 查询并将它们与方法调用相关联。编译器检查 SQL 是否有错误,然后从注释中生成查询。对于常见查询,库提供了方便的注释,例如@Insert.

注意:

DAO 必须是一个interfaceabstract类。Room 使用 DAO 为您的代码创建干净的 API。默认情况下,所有查询 (@Query) 必须在主线程以外的线程上执行。(您稍后再处理。)对于插入或删除等操作,如果您使用提供的便利注释,Room 会为您处理线程管理。

实现DAO类

@Daopublic interface WordDao {@Insertvoid insert(Word word);@Query("DELETE FROM word_table")void deleteAll();@Query("SELECT * from word_table ORDER BY word ASC")List<Word> getAllWords();}

93.4 使用LiveData

在WordDao中返回LiveData

@Query("SELECT * from word_table ORDER BY word ASC")LiveData<List<Word>> getAllWords();

93.5 添加Room数据库

Room 是 SQLite 数据库之上的数据库层。Room 负责处理您过去使用数据库助手类(例如SQLiteOpenHelper.

Room 使用 DAO 向其数据库发出查询。默认情况下,为了避免糟糕的 UI 性能,Room 不允许您在主线程上发出数据库查询。LiveData需要时,通过在后台线程上自动异步运行查询来应用此规则。Room 提供 SQLite 语句的编译时检查。您的Room类必须是 abstract 和 extendRoomDatabase。通常,整个应用程序只需要一个 Room 数据库实例。

创建一个Room数据库

@Database(entities = {Word.class}, version = 1, exportSchema = false)public abstract class WordRoomDatabase extends RoomDatabase {public abstract WordDao wordDao();private static WordRoomDatabase INSTANCE;static WordRoomDatabase getDatabase(final Context context) {if (INSTANCE == null) {synchronized (WordRoomDatabase.class) {if (INSTANCE == null) {INSTANCE = Room.databaseBuilder(context.getApplicationContext(),WordRoomDatabase.class, "word_database")// Wipes and rebuilds instead of migrating // if no Migration object.// Migration is not part of this practical..fallbackToDestructiveMigration().build();}}}return INSTANCE;}}

93.6 创建存储库

实施存储库

public class WordRepository {private WordDao mWordDao;private LiveData<List<Word>> mAllWords;WordRepository(Application application) {WordRoomDatabase db = WordRoomDatabase.getDatabase(application);mWordDao = db.wordDao();mAllWords = mWordDao.getAllWords();}LiveData<List<Word>> getAllWords() {return mAllWords;}public void insert (Word word) {new insertAsyncTask(mWordDao).execute(word);}private static class insertAsyncTask extends AsyncTask<Word, Void, Void> {private WordDao mAsyncTaskDao;insertAsyncTask(WordDao dao) {mAsyncTaskDao = dao;}@Overrideprotected Void doInBackground(final Word... params) {mAsyncTaskDao.insert(params[0]);return null;}}}

93.7 创建ViewModel

实现WordViewModel

public class WordViewModel extends AndroidViewModel {private WordRepository mRepository;private LiveData<List<Word>> mAllWords;public WordViewModel (Application application) {super(application);mRepository = new WordRepository(application);mAllWords = mRepository.getAllWords();}LiveData<List<Word>> getAllWords() {return mAllWords; }public void insert(Word word) {mRepository.insert(word); }}

93.8 为UI添加XML布局
添加样式添加布局添加回收站视图修改FAB图标
93.9 创建一个Adapter并添加RecylerView

创建 WordListAdapter 类

public class WordListAdapter extends RecyclerView.Adapter<WordListAdapter.WordViewHolder> {private final LayoutInflater mInflater;private List<Word> mWords; // Cached copy of wordsWordListAdapter(Context context) {mInflater = LayoutInflater.from(context); }@Overridepublic WordViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View itemView = mInflater.inflate(R.layout.recyclerview_item, parent, false);return new WordViewHolder(itemView);}@Overridepublic void onBindViewHolder(WordViewHolder holder, int position) {if (mWords != null) {Word current = mWords.get(position);holder.wordItemView.setText(current.getWord());} else {// Covers the case of data not being ready yet.holder.wordItemView.setText("No Word");}}void setWords(List<Word> words){mWords = words;notifyDataSetChanged();}// getItemCount() is called many times, and when it is first called,// mWords has not been updated (means initially, it's null, and we can't return null).@Overridepublic int getItemCount() {if (mWords != null)return mWords.size();else return 0;}class WordViewHolder extends RecyclerView.ViewHolder {private final TextView wordItemView;private WordViewHolder(View itemView) {super(itemView);wordItemView = itemView.findViewById(R.id.textView);}}}

将 RecyclerView 添加到 MainActivity

RecyclerView recyclerView = findViewById(R.id.recyclerview);final WordListAdapter adapter = new WordListAdapter(this);recyclerView.setAdapter(adapter);recyclerView.setLayoutManager(new LinearLayoutManager(this));

93.10 填充数据库

创建用于填充数据库的回调

private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {private final WordDao mDao;String[] words = {"dolphin", "crocodile", "cobra"};PopulateDbAsync(WordRoomDatabase db) {mDao = db.wordDao();}@Overrideprotected Void doInBackground(final Void... params) {// Start the app with a clean database every time.// Not needed if you only populate the database// when it is first createdmDao.deleteAll();for (int i = 0; i <= words.length - 1; i++) {Word word = new Word(words[i]);mDao.insert(word);}return null;}}

93.11 将UI与数据连接起来

显示单词

mWordViewModel.getAllWords().observe(this, new Observer<List<Word>>() {@Overridepublic void onChanged(@Nullable final List<Word> words) {// Update the cached copy of the words in the adapter.adapter.setWords(words);}});

93.12 创建一个用于添加单词的Activity

public class NewWordActivity extends AppCompatActivity {public static final String EXTRA_REPLY = "com.example.android.roomwordssample.REPLY";private EditText mEditWordView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_new_word);mEditWordView = findViewById(R.id.edit_word);final Button button = findViewById(R.id.button_save);button.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {Intent replyIntent = new Intent();if (TextUtils.isEmpty(mEditWordView.getText())) {setResult(RESULT_CANCELED, replyIntent);} else {String word = mEditWordView.getText().toString();replyIntent.putExtra(EXTRA_REPLY, word);setResult(RESULT_OK, replyIntent);}finish();}});}}

将单词插入数据库的代码

public void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == NEW_WORD_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {Word word = new Word(data.getStringExtra(NewWordActivity.EXTRA_REPLY));mWordViewModel.insert(word);} else {Toast.makeText(getApplicationContext(),R.string.empty_not_saved,Toast.LENGTH_LONG).show();}}

93.13 小结
MainActivity您有一个应用程序可以在列表 ( ,RecyclerView,WordListAdapter)中显示单词。您可以将单词添加到列表 (NewWordActivity)。一个词是Word实体类的一个实例。单词被缓存在RecyclerViewAdapter单词List(mWords) 中。当数据发生变化时,列表会自动更新并重新显示。发生自动更新是因为在 中MainActivity,有一个Observer观察单词并在单词更改时收到通知。当有变化时,观察者的onChange()方法被执行并mWordsWordListAdapter.可以观察到数据,因为它是LiveData。观察到的是对象LiveData<List<Word>>返回的WordViewModelWordViewModel从用户界面隐藏有关后端的所有内容。它提供了访问 UI 数据的方法,并返回LiveData以便MainActivity可以设置观察者关系。视图、活动和片段仅通过ViewModel. 因此,数据来自哪里并不重要。在这种情况下,数据来自存储库。ViewModel不需要知道存储库与什么交互。它只需要知道如何与Repository 交互,就是通过Repository 暴露的方法。存储库管理一个或多个数据源。在 RoomWordsSample 应用程序中,该后端是 Room 数据库。Room 是一个包装器并实现了一个 SQLite 数据库。Room 为您做了很多以前必须自己做的工作。例如,Room 可以完成您过去使用SQLiteOpenHelper类所做的所有事情。DAO 将方法调用映射到数据库查询,因此当 Repository 调用诸如 之类的方法时getAllWords(),Room 可以执行**。**SELECT * from word_table ORDER BY word ASC观察查询返回的结果LiveData。因此,每次 Room 中的数据发生变化时,都会执行Observer接口的onChanged()方法并更新 UI。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。