Room中碰到的问题

目录

  • 教程
  • Room
  • 使用中碰到的问题
    • Entity不支持的数据类型,如Date
          • 找到错误
          • 解决方法:
    • 错误:在主线程执行插入操作
          • 方法一、强制在主线程执行。(最懒、感觉不太保险的方法)
          • 方法二、模仿官网例子,在diskIO中执行插入操作(正在使用的方法)
          • 方法三、继承AsyncTask(代码略长,不想用的方法)

教程

先看基本用法,边看边练。然后参考官网例子,学习如何在生产环境中使用。
视频教程:av50954019(bilibili)。我刚开始跟这个up主学,讲的很仔细。学习一些简单用法后,啃官网指南和例子。
Room的基本用法:https://developer.android.com/training/data-storage/room/index.html
Code Lab练手:https://codelabs.developers.google.com/codelabs/android-room-with-a-view/#0

官网例子:Android架构组件实例 学习创建单例Database、与RxJava一起使用、与Paging库使用等,大多数是Kotlin的,官网前几个例子是用Java写的。

Room

应用架构指南中推荐应用架构有个Repository(数据仓库),它负责从网络或数据库中获取数据。Room就是负责对数据库操作的,它在 SQLite 的基础上提供了一个抽象层,通过注解的方式让我们更方便的使用SQLite。

从数据库获取数据
从网络获取数据
Repository
Retrofit/OkHttp等
Database
Dao
Entity

Room主要包含下面三个组件:

  1. @Entity(相当于关系表)
  2. @Dao(interface,包含增删查改)
  3. @Database (单例创建数据库,包含@Dao类的抽象方法)

使用中碰到的问题

Entity不支持的数据类型,如Date

找到错误

注意:一定要加 annotationProcessor "androidx.room:room-compiler:2.1.0",它能提示你具体哪里错了,如entity中不支持的数据类型 导致 Room.databaseBuilder(xxx).build中 .build 错误,双击错误,跳到不兼容的数据类型那里;

错误: Cannot figure out how to save this field into database. You can consider adding a type converter for it.

否则只提示:

Caused by: java.lang.RuntimeException: cannot find implementation for com.xxx.xxxDatabase. xxxDatabase_Impl does not exist
解决方法:

Entity仅支持基本数据类型,如int,String等。若想使用Date,参考 使用 Room 引用复杂数据。

错误:在主线程执行插入操作

目前本人已知的三种方法,不代表全部

方法一、强制在主线程执行。(最懒、感觉不太保险的方法)

创建Database时:添加.allowMainThreadQueries()

	Room.databaseBuilder(this,xxxDatabase.class,"数据库名")
	 .allowMainThreadQueries()
	 .build();
方法二、模仿官网例子,在diskIO中执行插入操作(正在使用的方法)

添加类:AppExecutors.java:mainThread、diskIO、networkIO
使用:

  1. 自定义Application
public class BaseApplication extends Application {
     
    private AppExecutors mAppExecutors;

    @Override
    public void onCreate() {
     
        super.onCreate();
        mAppExecutors = new AppExecutors();
    }

    public AppExecutors getAppExecutors() {
     
        return mAppExecutors;
    }

    public BaseApplication getBaseApplication() {
     
        return this;
    }
}
  1. 获取AppExecutors 并使用 。
	private AppExecutors mExecutors;
	mExecutors = ((BaseApplication) application).getAppExecutors();
	
	// 使用。结合自己的数据库操作,替换{}内的内容。
	mExecutors.diskIO().execute(() -> {
     
		// 插入操作,如某Dao().insert(xxxEntity)
		mDatabase.mxxxDao().insertxxx(xxxentity);
    });
方法三、继承AsyncTask(代码略长,不想用的方法)
	//
	void insertWords(Word... words) {
     
        new InsertAsyncTask(wordDao).execute(words);
    }
	static class InsertAsyncTask extends AsyncTask<Word, Void, Void> {
     
        private WordDao wordDao;

        InsertAsyncTask(WordDao wordDao) {
     
            this.wordDao = wordDao;
        }

        @Override
        protected Void doInBackground(Word... words) {
     
            wordDao.insertWords(words);
            return null;
        }

    }

你可能感兴趣的:(笔记)