Realm源码下载
上篇Realm总结是关于Realm的基础使用,可粗略地概括为如下关系图:
在感受了Realm的强大之后,更让人对其背后的实现原理感到好奇,点击下载Realm源码一探究竟吧。
目前Realm java的版本是3.5,如下工程截图,模块简介如下:
- realm-java工程囊括了好几个模块,而编译配置说明是在工程根目录下的README.md
- examples模块是realm提供的使用demo
- gradle-plugin模块是realm编译使用的插件
- realm模块则是这个工程的核心,java与c++代码都这里。
- realm-annotations模块是realm使用到的注解,如PrimaryKey
- realm-transformer模块是在编译时辅助生成realm代码,非常重要的模块。
Realm初始化
使用Realm的第一步是调用Realm.init(this),源码如下:
public static synchronized void init(Context context) { if (BaseRealm.applicationContext == null) { if (context == null) { throw new IllegalArgumentException("Non-null context required."); } // 检查是否能范围应用的数据存储空间的目录 checkFilesDirAvailable(context); // 加载 librealm-jni.so RealmCore.loadLibrary(context); // 关键点:设置Realm默认配置 setDefaultConfiguration(new RealmConfiguration.Builder(context).build()); ObjectServerFacade.getSyncFacadeIfPossible().init(context); BaseRealm.applicationContext = context.getApplicationContext(); SharedRealm.initialize(new File(context.getFilesDir(), ".realm.temp")); } }
Realm配置封装在RealmConfiguration,以Builder模式实现定制化需求。先看RealmConfiguration.Builder的build方法,源码如下:
public RealmConfiguration build() { //忽略前面的合法性判断 return new RealmConfiguration(directory, fileName, getCanonicalPath(new File(directory, fileName)), assetFilePath, key, schemaVersion, migration, deleteRealmIfMigrationNeeded, durability, createSchemaMediator(modules, debugSchema), rxFactory, initialDataTransaction, readOnly, compactOnLaunch ); }
从上面的build方法来看,参数的传递需要从Builder构造方法来追踪,继续查看Builder的构造方法源码:
{ public Builder() { this(BaseRealm.applicationContext); } Builder(Context context) { if (context == null) { throw new IllegalStateException("Call `Realm.init(Context)` before creating a RealmConfiguration"); } RealmCore.loadLibrary(context); initializeBuilder(context); } private void initializeBuilder(Context context) { this.directory = context.getFilesDir(); this.fileName = Realm.DEFAULT_REALM_NAME; this.key = null; this.schemaVersion = 0; this.migration = null; this.deleteRealmIfMigrationNeeded = false; this.durability = SharedRealm.Durability.FULL; this.readOnly = false; this.compactOnLaunch = null; if (DEFAULT_MODULE != null) { this.modules.add(DEFAULT_MODULE); } } }
从initializeBuilder可以确定,Builder已经为RealmConfiguration配置项提供了默认值,比如指定了存储位置、文件名、版本号等。其中modules这属性是关键点,因为它是后面构造RealmProxyMediator实例的关键。先看这个DEFAULT_MODULE,相关源码如下:
private static final Object DEFAULT_MODULE; protected static final RealmProxyMediator DEFAULT_MODULE_MEDIATOR; //没想到居然是以静态代码块的方式来实例化的。 static { DEFAULT_MODULE = Realm.getDefaultModule();