前言
之前已经讲了ObjectBox的基本配置,网上已经讲了很多ObjectBox的相关知识,但是ObjectBox的数据库存储路径问题,却极少提到,这节就让我们来探究下ObjectBox的数据存储路径吧。
今天涉及的知识有:
- ObjectBox数据库默认存储路径
- ObjectBox自定义存储路径
- ObjectBox数据库管理类封装
一.ObjectBox数据库默认存储路径
在使用Objectbox进行数据处理之前,我们先要初始化ObjectBox数据库,这时会涉及到BoxStore的初始化,让我们来看看初始化ObjectBox数据库代码吧:
private static BoxStore boxStore;
boxStore = MyObjectBox.builder()
.androidContext(context.getApplicationContext())
.build();
这段代码会在你项目的application中初始化。其中,让我们来看看
androidContext(context.getApplicationContext())
方法,追踪源码,会看到以下代码:
public BoxStoreBuilder androidContext(Object context) {
if (context == null) {
throw new NullPointerException("Context may not be null");
}
this.context = getApplicationContext(context);
File baseDir = getAndroidBaseDir(context);
if (!baseDir.exists()) {
baseDir.mkdir();
if (!baseDir.exists()) { // check baseDir.exists() because of potential concurrent processes
throw new RuntimeException("Could not init Android base dir at " + baseDir.getAbsolutePath());
}
}
if (!baseDir.isDirectory()) {
throw new RuntimeException("Android base dir is not a dir: " + baseDir.getAbsolutePath());
}
baseDirectory = baseDir;
android = true;
return this;
}
继续看其中涉及到的 getAndroidBaseDir(context) 方法:
static File getAndroidBaseDir(Object context) {
return new File(getAndroidFilesDir(context), "objectbox");
}
这里我们看到创建了一个File,getAndroidFilesDir(context)是一个路径,然后后面跟了一个"objectbox"值,"objectbox"是该路径下的一个文件夹名称,接着往下看
@Nonnull
private static File getAndroidFilesDir(Object context) {
File filesDir;
try {
Method getFilesDir = context.getClass().getMethod("getFilesDir");
filesDir = (File) getFilesDir.invoke(context);
if (filesDir == null) {
// Race condition in Android before 4.4: https://issuetracker.google.com/issues/36918154 ?
System.err.println("getFilesDir() returned null - retrying once...");
filesDir = (File) getFilesDir.invoke(context);
}
} catch (Exception e) {
throw new RuntimeException(
"Could not init with given Android context (must be sub class of android.content.Context)", e);
}
if (filesDir == null) {
throw new IllegalStateException("Android files dir is null");
}
if (!filesDir.exists()) {
throw new IllegalStateException("Android files dir does not exist");
}
return filesDir;
}
ok, getAndroidFilesDir(Object context) 方法其实是创建了一个文件夹路径。
接着我们看
boxStore = MyObjectBox.builder()
.androidContext(context.getApplicationContext())
.build();
中 的 “ .build()” 方法,追踪源码,显示如下:
/**
* Builds a {@link BoxStore} using any given configuration.
*/
public BoxStore build() {
if (directory == null) {
name = dbName(name);
directory = getDbDir(baseDirectory, name);
}
checkProvisionInitialDbFile();
return new BoxStore(this);
}
继续看 dbName(name) 方法:
private static String dbName(@Nullable String dbNameOrNull) {
return dbNameOrNull != null ? dbNameOrNull : DEFAULT_NAME;
}
这里出现了当 dbName(name)方法中的 name为null时,会设置一个默认name=DEFAULT_NAME,接着看追踪DEFAULT_NAME:
public static final String DEFAULT_NAME = "objectbox";
结合“ .build()” 方法
/**
* Builds a {@link BoxStore} using any given configuration.
*/
public BoxStore build() {
if (directory == null) {
name = dbName(name);
directory = getDbDir(baseDirectory, name);
}
checkProvisionInitialDbFile();
return new BoxStore(this);
}
会发现以上 的都是在设置数据库的文件夹路径directory,所以由此看ObjectBox存储路径是 getAndroidFilesDir(Object context) / objectbox /objectbox/ ,接着我们看看ObjectBox数据库文件名及文件格式。接着看 “ .build()” 方法 中的:
checkProvisionInitialDbFile();
追踪看看:
private void checkProvisionInitialDbFile() {
if (initialDbFileFactory != null) {
String dataDir = BoxStore.getCanonicalPath(directory);
File file = new File(dataDir, "data.mdb");
if (!file.exists()) {
InputStream in = null;
OutputStream out = null;
try {
in = initialDbFileFactory.provide();
if (in == null) {
throw new DbException("Factory did not provide a resource");
}
in = new BufferedInputStream(in);
out = new BufferedOutputStream(new FileOutputStream(file));
IoUtils.copyAllBytes(in, out);
} catch (Exception e) {
throw new DbException("Could not provision initial data file", e);
} finally {
IoUtils.safeClose(out);
IoUtils.safeClose(in);
}
}
}
}
其中有一行:
File file = new File(dataDir, "data.mdb");
据此,我们知道ObjectBox的存储默认文件为:"data.mdb 。
ok,通过以上的追踪,得出ObjectBox默认存储路径为:
getAndroidFilesDir(Object context) / objectbox /objectbox/ data.mdb
由于getAndroidFilesDir(Object context)是源码中一个私有方法。第一种方案,你可以将此方法拷贝出来,然后运行查看路径。第二种方案:我们大致可以看出此路径是在项目app的内部的,这里我直接运行自己的项目,然后查看手机app安装目录,在
/data/data/app包名/files/objectbox/objectbox/ 目录下看到以下截图
即,当 BoxStore 在初始化时,以:
public static void init(Context context) {
boxStore = MyObjectBox.builder()
.androidContext(context.getApplicationContext())
.build();
LogUtil.i("===BoxStore.version="+BoxStore.getVersion()+" BoxStore.versionNative="+BoxStore.getVersionNative());
}
方式创建的时候,ObjectBox数据库默认文件存储路径为:
/data/data/app包名/files/objectbox/objectbox/data.mdb
二.ObjectBox自定义存储路径
经过上面的研究,我们可以发现 boxStore对象是通过