12.从架构设计角度分析AAC源码-Room源码解析第1篇:当前demo为主线查看涉及的Room源码解析

前言

下面的解析也是总体到细节去一步步剥离当前demo为主线涉及的Room源码部分。

demo

demo路径在AAC-core-demo下(下载当前github上的源码是记得是Room tag标签)。

我们应该运行一下当前demo,知道它是干什么的

12.从架构设计角度分析AAC源码-Room源码解析第1篇:当前demo为主线查看涉及的Room源码解析_第1张图片

  1. 在输入框输入随意信息,e.g. 啦啦啦;

  2. 点击按钮 UPDATE USERENAME,当前输入框会更新如图所示的输入框上方;

  3. 关闭当前app,再次打开上次输入的信息(e.g.啦啦啦)被保留并展示在如图所示的输入框上方。

出现这种情况的原因:我们使用了androidx源码中的room组件。通过room操作supportSqlite,supportSqlite再去操作android源码中的sqlite组件。

  • 知道是Room插件即可,这里的supportSqlite就是androidx源码中sqlite组件的具体实现几个类,前缀都是supportSQLite。

总体到细节

下面开始一步步深入细节的去理解当前Room源码。

12.从架构设计角度分析AAC源码-Room源码解析第1篇:当前demo为主线查看涉及的Room源码解析_第2张图片

  1. app模块:demo模块,使用Room;

  2. room模块:设计到的子模块不只是上面的两个,room-runtime和room-compiler,我们暂主要理解这两个即可;

  • (1) room-runtime:被demo引用的依赖,通过当前模块去操作数据库,相当于把数据库的操作分为两部分:一部分自己处理,一部分交给androidx中sqlite模块去处理;

  • (2) room-compiler:用于根据demo中的注解,为demo生成类(这里不做研究,后面会有专门的文章去分析,以及room注解的用法);

  • (3)补:还有room-rxjava2:当前为了room兼容使用rxjava2;

  1. sqlite模块:两个子模块,一个子模块还叫sqlite,一个子模块是sqlite-framework;
  • (1)sqlite:定义supportSqlite各个类,类方法实际还是沿用android源码中的sqlite组件中的方法;room组件中使用的是该sqlite子模块的类
  • (2)sqlite-framework:①实现sqlite子模块接口,所以room组件中使用的虽然是sqlite子模块类,但是实际还是sqlite-framework中的实现类;②当前类通过代理方式实现android源码中的sqlite组件方法;③生成android源码中的sqlite组件的类作为framework类的代理;

下面针对每个模块,有外向内一步步讲解:

app模块

12.从架构设计角度分析AAC源码-Room源码解析第1篇:当前demo为主线查看涉及的Room源码解析_第3张图片

描述写的越多越乱,第一是个人水平问题;第二,是确实不易写的那么全,看起来乱的很。我感觉这样挺清晰的。

如果所示,这里采用的是MVVM模式,下面对当前框架进行简单讲解,较简单:

  1. Activity从ViewModel获取数据,ViewModel从UserDataSource中获取数据;

  2. Injection(使用了注解思想,理解注解应该非常容易理解这种实现方式)类启到衔接作用:

  • (1)提供ViewModelFactory生成ViewModel实例;
  • (2)为生成ViewModel实例提供构造函数参数UserDataSource,实际给的是UserDataSource的子类LocalUserDataSource;
  • (3)实例化UserDatabase,将UserDataBase中的userDao作为LocalUserDataSource类构造函数参数;
  1. 所以VieModel中操作的UserDataSource实际是LocalUserDataSource类;

  2. UserDataBase类的操作我们作为Room模块讲解,这里可以当做暗箱来理解。

room模块

当前demo为主线解说room源码,我们分为两步骤来解说:(1)room初始化工作;(2)room操作数据库操作:①插入或更新数据库,②查询;

涉及到room注解部分(如xxx_Impl类)会单独有一章介绍room注解的具体使用;sqlite部分(SupportSQLite的实例化)下面sqlite模块部分会做讲解。

room初始化

12.从架构设计角度分析AAC源码-Room源码解析第1篇:当前demo为主线查看涉及的Room源码解析_第4张图片

如上图所示,room初始化的重要作用有两个:

  1. 返回的UsersDatabase实例对象是UsersDatabase_Impl;

  2. 新建了FrameworkSQLiteOpenHelperFactory对象,当前对象的作用是创建FrameworkSQLiteOpenHelper类;

简单讲解下上图流程:

  1. app模块调用UserDatabase类的getInstance()方法实例化;

  2. UsersDatabase继承RoomDatabase类,RoomDatabase是通过Builder构造者模式构建的,所以这里调用的是RoomDatabase的build()方法; build()方法做了3件事情:

  • (1)实例化很多参数,这里比较重要的是mQueryExecutor = mTransactionExecutor线程池factory = new FrameworkSQLiteOpenHelperFactory,将实例化后的参数传递给DatabaseConfiguration(字面意思:存储数据库配置信息);

  • (2)调用Room的getGeneratedImplementation()方法,根据注解命名规则实例化UsersDatabase_impl类,该类继承UsersDatabase(UsersDatabase继承RoomDatabase类);

  • (3)调用RoomDatabase的init()方法,该方法调用createOpenHelper()抽象方法,具体实现在UsersDatabase_Impl类中;

  1. UsersDatabase_Impl类的createOpenHelper()方法返回SupportSQLiteOpenHelper接口对象,这里通过DatabaseConfiguration类中的factory参数factory = new FrameworkSQLiteOpenHelperFactory调用create()方法创建FrameworkSQLiteOpenHelper对象作为实际返回对象;
  • createOpenHelper()方法中的RoomOpenHelper等等,先别急着看,用到了再说,很多虽然存在,但是不一定用到了。

room操作数据库

12.从架构设计角度分析AAC源码-Room源码解析第1篇:当前demo为主线查看涉及的Room源码解析_第5张图片

如上图,实际操作数据库部分并不难,但是需要注意的是这里操作数据库的几个类:SupportSQLiteStatement和SupportSQLiteDatabase实际实例对象分别是FrameworkSQLiteStatement和FrameworkSQLiteDatabase,并且这里操作数据库都是通过RoomDatabase中的SupportSQLiteOpenHelper mOpenHelper来控制。

疑问:CREATE TABLE IF NOT EXISTS users在哪???

答:存在于UsersDatabase_Impl的createOpenHelper()方法中了,如下图

12.从架构设计角度分析AAC源码-Room源码解析第1篇:当前demo为主线查看涉及的Room源码解析_第6张图片

至于如何调用关下,请听下面sqlite模块的讲解。

sqlite模块

前一章说了Sqlite模块,但是说的一头雾水,看的也是一脸懵逼。这里可以相对来说较详细对它进一步理解了。

  1. 在RoomDatabase中统一管理SupportSQLiteOpenHelper mOpenHelper
  • (1)需要操作数据库必须使用mOpenHelper参数;
  • (2)操作数据库必须调用RoomDatabase中的mOpenHelper参数;
  1. SupportSQLiteOpenHelper mOpenHelper实例化在UserDatabase_Impl类的createOpenHelper()方法中;

  2. 执行FrameworkSqLiteOpenHelper的方法,实际执行的是getDelegate()代理中的方法,代理返回的是OpenHelper对象,OpenHelper对象继承SQLiteOpenHelper类,由此可知Sqlite的核心是理解FrameworkSQLiteOpenHelper类中的OpenHelper类;

  3. 查看OpenHelper类:

  • (1)查看getSupportDatabase()方法,返回的是SupportSQLiteDatabase接口对象,该方法:①调用innerGetDatabase()方法,如果Sample.db文件不存在则创建;并且获取读或写权限SQLiteDatabase对象;②将获取读或写权限SQLiteDatabase对象作为FrameworkSQLiteDatabase类构造函数参数,对FrameworkSQLiteDatabase实例化。所以实际返回的是FrameworkSQLiteDatabase类,并且该类的所有方法操作的是用读或写权限SQLiteDatabase代理对象的方法;

  • (2)onCreate()方法,调用SupportSQLiteOpenHelper接口内部类Callback的onCreate()方法,①该Callback抽象类在UserDatabase_Impl类的createOpenHelper()方法中被实现RoomOpenHelper类;②RoomOpenHelper类的onCreate方法调用Delegate抽象类的createAllTables()方法,也就是回答了上面CREATE TABLE IF NOT EXISTS users在哪???的问题

总结

个人感觉解说的还行。其实源码我来回看了很多遍,细节部分都没有放弃,写这篇文章很有必要,能够把零散的东西通过这篇文章整合成一个有架构感的设计思想。

你可能感兴趣的:(源码解析,sqlite,android,数据库)