一、SQLite源码解析
(1)SQLiteOpenHelper源码
public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,
@Nullable CursorFactory factory, int version) {
this(context, name, factory, version, null);
}
public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,
@Nullable CursorFactory factory, int version,
@Nullable DatabaseErrorHandler errorHandler) {
this(context, name, factory, version, 0, errorHandler);
}
public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,
@Nullable CursorFactory factory, int version,
int minimumSupportedVersion, @Nullable DatabaseErrorHandler errorHandler) {
this(context, name, version, minimumSupportedVersion,
new SQLiteDatabase.OpenParams.Builder());
mOpenParamsBuilder.setCursorFactory(factory);
mOpenParamsBuilder.setErrorHandler(errorHandler);
}
private SQLiteOpenHelper(@Nullable Context context, @Nullable String name, int version,
int minimumSupportedVersion,
@NonNull SQLiteDatabase.OpenParams.Builder openParamsBuilder) {
Preconditions.checkNotNull(openParamsBuilder);
if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version);
mContext = context;
mName = name;
mNewVersion = version;
mMinimumSupportedVersion = Math.max(0, minimumSupportedVersion);
setOpenParamsBuilder(openParamsBuilder);
}
(2)SQLiteOpenHelper.getWritableDatabase与getReadableDatabase源码
//获得一个可读写的数据库
public SQLiteDatabase getWritableDatabase() {
synchronized (this) {
return getDatabaseLocked(true);
}
}
//获得一个只读的数据库
public SQLiteDatabase getReadableDatabase() {
synchronized (this) {
return getDatabaseLocked(false);
}
}
private SQLiteDatabase getDatabaseLocked(boolean writable) {
if (mDatabase != null) {
if (!mDatabase.isOpen()) {
//如果数据库已经关闭,需要重新打开
mDatabase = null;
} else if (!writable || !mDatabase.isReadOnly()) {
//数据库没有关闭,直接返回
return mDatabase;
}
}
SQLiteDatabase db = mDatabase;
try {
mIsInitializing = true;
if (db != null) {
if (writable && db.isReadOnly()) {
//当前数据是只读状态,需要获取可写的数据库
db.reopenReadWrite();
}
} else if (mName == null) {
//数据库名称为null,为Memory Db
db = SQLiteDatabase.createInMemory(mOpenParamsBuilder.build());
} else {
//获取数据库保存路径
final File filePath = mContext.getDatabasePath(mName);
//数据库创建的相关配置项
SQLiteDatabase.OpenParams params = mOpenParamsBuilder.build();
try {
//创建数据库操作SQLiteDatabase实例
db = SQLiteDatabase.openDatabase(filePath, params);
setFilePermissionsForDb(filePath.getPath());
} catch (SQLException ex) {
if (writable) {
throw ex;
}
params = params.toBuilder().addOpenFlags(SQLiteDatabase.OPEN_READONLY).build();
db = SQLiteDatabase.openDatabase(filePath, params);
}
}
//创建数据库成功,回调此方法配置数据库
onConfigure(db);
//获取当前数据库版本,默认为0
final int version = db.getVersion();
//mNewVersion是自行设置的版本号
if (version != mNewVersion) {
//此时如果是只读状态,将无法对数据库做任何更改
if (db.isReadOnly()) {
throw new SQLiteException("Can't upgrade read-only database from version " +
db.getVersion() + " to " + mNewVersion + ": " + mName);
}
//如果当前版本号小于最小支持的版本,删除数据库
if (version > 0 && version < mMinimumSupportedVersion) {
File databaseFile = new File(db.getPath());
onBeforeDelete(db);
db.close();
//删除数据库文件
if (SQLiteDatabase.deleteDatabase(databaseFile)) {
mIsInitializing = false;
//删除成功重新创建数据库
return getDatabaseLocked(writable);
} else {
throw new IllegalStateException("Unable to delete obsolete database "
+ mName + " with version " + version);
}
} else {
//开启事务
db.beginTransaction();
try {
//数据库第一次创建回调执行onCreate
if (version == 0) {
onCreate(db);
} else {
if (version > mNewVersion) {
//降级回调
onDowngrade(db, version, mNewVersion);
} else {
//升级回调
onUpgrade(db, version, mNewVersion);
}
}
//设置当前最后版本
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
}
//表示数据库已经打开回调
onOpen(db);
//赋值给当前成员
mDatabase = db;
return db;
} finally {
mIsInitializing = false;
if (db != null && db != mDatabase) {
db.close();
}
}
}
//获取自定义或默认路径
@Override
public File getDatabasePath(String name) {
File dir;
File f;
if (name.charAt(0) == File.separatorChar) {
//自定义存储路径
String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
dir = new File(dirPath);
name = name.substring(name.lastIndexOf(File.separatorChar));
f = new File(dir, name);
if (!dir.isDirectory() && dir.mkdir()) {
FileUtils.setPermissions(dir.getPath(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
-1, -1);
}
} else {
//默认路径
dir = getDatabasesDir();
f = makeFilename(dir, name);
}
return f;
}
public static final class OpenParams {
//保存当前数据库相关配置
private OpenParams(int openFlags, CursorFactory cursorFactory,
DatabaseErrorHandler errorHandler, int lookasideSlotSize, int lookasideSlotCount,
long idleConnectionTimeout, String journalMode, String syncMode) {
//打开模式
mOpenFlags = openFlags;
//Cursor工厂
mCursorFactory = cursorFactory;
mErrorHandler = errorHandler;
mLookasideSlotSize = lookasideSlotSize;
mLookasideSlotCount = lookasideSlotCount;
//空闲连接超时时间
mIdleConnectionTimeout = idleConnectionTimeout;
//日志模式
mJournalMode = journalMode;
//同步模式
mSyncMode = syncMode;
}
}
SQLiteOpenHelper主要完成SQLiteDatabase 的创建、关闭、升/降级、配置等相关辅助管理
(3)SQLiteDatabase.openDatabase获取SQLiteDatabase实例源码
public static SQLiteDatabase openDatabase(@NonNull File path,
@NonNull OpenParams openParams) {
return openDatabase(path.getPath(), openParams);
}
private static SQLiteDatabase openDatabase(@NonNull String path,
@NonNull OpenParams openParams) {
Preconditions.checkArgument(openParams != null, "OpenParams cannot be null");
//创建SQLiteDatabase实例,将OpenParams配置参数传入SQLiteDatabase
SQLiteDatabase db = new SQLiteDatabase(path, openParams.mOpenFlags,
openParams.mCursorFactory, openParams.mErrorHandler,
openParams.mLookasideSlotSize, openParams.mLookasideSlotCount,
openParams.mIdleConnectionTimeout, openParams.mJournalMode, openParams.mSyncMode);
//调用SQLiteDatabase的open
db.open();
return db;
}
//将前面保存相关创建配置的 OpenParams 信息保存到 SQLiteDatabaseConfiguartion 中
private SQLiteDatabase(final String path, final int openFlags,
CursorFactory cursorFactory, DatabaseErrorHandler errorHandler,
int lookasideSlotSize, int lookasideSlotCount, long idleConnectionTimeoutMs,
String journalMode, String syncMode) {
mCursorFactory = cursorFactory;
mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler();
//SQLiteDatabase的创建模式,主要影响数据库连接池打开模式
mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags);
mConfigurationLocked.lookasideSlotSize = lookasideSlotSize;
mConfigurationLocked.lookasideSlotCount = lookasideSlotCount;
//禁用低内存设备上的lookaside分配器
if (ActivityManager.isLowRamDeviceStatic()) {
mConfigurationLocked.lookasideSlotCount = 0;
mConfigurationLocked.lookasideSlotSize = 0;
}
long effectiveTimeoutMs = Long.MAX_VALUE;
// Never close idle connections for in-memory databases
if (!mConfigurationLocked.isInMemoryDb()) {
//空闲连接超时,默认值-1表示未设置值
if (idleConnectionTimeoutMs >= 0) {
effectiveTimeoutMs = idleConnectionTimeoutMs;
} else if (DEBUG_CLOSE_IDLE_CONNECTIONS) {
//默认为false,表示空闲连接不会被关闭
effectiveTimeoutMs = SQLiteGlobal.getIdleConnectionTimeout();
}
}
mConfigurationLocked.idleConnectionTimeoutMs = effectiveTimeoutMs;
mConfigurationLocked.journalMode = journalMode;
mConfigurationLocked.syncMode = syncMode;
if (!SQLiteGlobal.isCompatibilityWalSupported() || (
SQLiteCompatibilityWalFlags.areFlagsSet() && !SQLiteCompatibilityWalFlags
.isCompatibilityWalSupported())) {
//不支持兼容性WAL,则禁用掉兼容性WAL
mConfigurationLocked.openFlags |= DISABLE_COMPATIBILITY_WAL;
}
}
private void open() {
try {
try {
openInner();
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
openInner();
}
} catch (SQLiteException ex) {
close();
throw ex;
}
}
//创建当前SQLiteDatabase的数据库连接池SQLiteConnectionPool
private void openInner() {
synchronized (mLock) {
assert mConnectionPoolLocked == null;
//打开数据库连接池,ConfigurationLocked作为参数
mConnectionPoolLocked = SQLiteConnectionPool.open(mConfigurationLocked);
mCloseGuardLocked.open("close");
}
synchronized (sActiveDatabases) {
//缓存当前SQLiteDatabase实例
sActiveDatabases.put(this, null);
}
}
(4)SQLiteConnectionPool.open源码
public static SQLiteConnectionPool open(SQLiteDatabaseConfiguration configuration) {
if (configuration == null) {
throw new IllegalArgumentException("configuration must not be null.");
}
//创建数据库连接池
SQLiteConnectionPool pool = new SQLiteConnectionPool(configuration);
//调用open可能抛出异常
pool.open();
return pool;
}
private SQLiteConnectionPool(SQLiteDatabaseConfiguration configuration) {
mConfiguration = new SQLiteDatabaseConfiguration(configuration);
//设置连接池的大小
setMaxConnectionPoolSizeLocked();
//在Long.MAX_VALUE下永远不会关闭连接
if (mConfiguration.idleConnectionTimeoutMs != Long.MAX_VALUE) {
//超时管理的Handler
setupIdleConnectionHandler(Looper.getMainLooper(),
mConfiguration.idleConnectionTimeoutMs);
}
}
private void setMaxConnectionPoolSizeLocked() {
if (!mConfiguration.isInMemoryDb()
&& (mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) {
mMaxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
} else {
mMaxConnectionPoolSize = 1;
}
}
//SQLiteGlobal.java
public static int getWALConnectionPoolSize() {
int value = SystemProperties.getInt("debug.sqlite.wal.poolsize",
Resources.getSystem().getInteger(
com.android.internal.R.integer.db_connection_pool_size));
//连接池默认最小为2,最大取决于系统配置
return Math.max(2, value);
}
@VisibleForTesting
public void setupIdleConnectionHandler(Looper looper, long timeoutMs) {
synchronized (mLock) {
//创建IdleConnectionHandler,超时管理的Handler
mIdleConnectionHandler = new IdleConnectionHandler(looper, timeoutMs);
}
}
private class IdleConnectionHandler extends Handler {
//保存配置的空闲连接超时时间
private final long mTimeout;
IdleConnectionHandler(Looper looper, long timeout) {
super(looper);
mTimeout = timeout;
}
@Override
public void handleMessage(Message msg) {
// Skip the (obsolete) message if the handler has changed
synchronized (mLock) {
if (this != mIdleConnectionHandler) {
return;
}
//关闭空闲超时的SQLiteConnection
if (closeAvailableConnectionLocked(msg.what)) {
}
}
}
void connectionReleased(SQLiteConnection con) {
//根据连接id,发送超时消息
sendEmptyMessageDelayed(con.getConnectionId(), mTimeout);
}
void connectionAcquired(SQLiteConnection con) {
removeMessages(con.getConnectionId());
}
void connectionClosed(SQLiteConnection con) {
//移除当前超时机制,说明连接被重新使用
removeMessages(con.getConnectionId());
}
}
private void open() {
//创建数据库主链接,只有主连接才可以写数据库,每一个数据库连接池默认仅有一条主连接
mAvailablePrimaryConnection = openConnectionLocked(mConfiguration,
true /*primaryConnection*/);
synchronized (mLock) {
if (mIdleConnectionHandler != null) {
//由于此时还没有任何使用,故开启空闲超时关闭机制
mIdleConnectionHandler.connectionReleased(mAvailablePrimaryConnection);
}
}
mIsOpen = true;
mCloseGuard.open("close");
}
private SQLiteConnection openConnectionLocked(SQLiteDatabaseConfiguration configuration,
boolean primaryConnection) {
//当前连接的唯一id
final int connectionId = mNextConnectionId++;
//创建连接
return SQLiteConnection.open(this, configuration,
connectionId, primaryConnection); // might throw
}
//从连接池获取到一个 SQLiteConnection
public SQLiteConnection acquireConnection(String sql, int connectionFlags,
CancellationSignal cancellationSignal) {
//获取一个SQLiteConnection
SQLiteConnection con = waitForConnection(sql, connectionFlags, cancellationSignal);
synchronized (mLock) {
if (mIdleConnectionHandler != null) {
//移除该连接的超时关闭消息
mIdleConnectionHandler.connectionAcquired(con);
}
}
return con;
}
//对该连接开启超时关闭机制
public void releaseConnection(SQLiteConnection connection) {
synchronized (mLock) {
if (mIdleConnectionHandler != null) {
//重新加入超时关闭机制
mIdleConnectionHandler.connectionReleased(connection);
}
//code...
}
}
(5)SQLiteConnection.open源码
static SQLiteConnection open(SQLiteConnectionPool pool,
SQLiteDatabaseConfiguration configuration,
int connectionId, boolean primaryConnection) {
//创建SQLiteConnection,每个SQLiteConnection对一个native层一个操作句柄
SQLiteConnection connection = new SQLiteConnection(pool, configuration,
connectionId, primaryConnection);
try {
//调用自己的open方法
connection.open();
return connection;
} catch (SQLiteException ex) {
connection.dispose(false);
throw ex;
}
}
private SQLiteConnection(SQLiteConnectionPool pool,
SQLiteDatabaseConfiguration configuration,
int connectionId, boolean primaryConnection) {
//持有数据库连接池
mPool = pool;
//操作日志
mRecentOperations = new OperationLog(mPool);
//持有数据库配置信息
mConfiguration = new SQLiteDatabaseConfiguration(configuration);
//该链接的唯一id
mConnectionId = connectionId;
//是否是主链接
mIsPrimaryConnection = primaryConnection;
//是否是只读模式
mIsReadOnlyConnection = (configuration.openFlags & SQLiteDatabase.OPEN_READONLY) != 0;
//缓存预编译后的SQL语句,内部采用LRU算法
mPreparedStatementCache = new PreparedStatementCache(
mConfiguration.maxSqlCacheSize);
mCloseGuard.open("close");
}
private void open() {
//创建数据库操作句柄
mConnectionPtr = nativeOpen(mConfiguration.path, mConfiguration.openFlags,
mConfiguration.label,
SQLiteDebug.DEBUG_SQL_STATEMENTS, SQLiteDebug.DEBUG_SQL_TIME,
mConfiguration.lookasideSlotSize, mConfiguration.lookasideSlotCount);
//设置页缓存大小
setPageSize();
setForeignKeyModeFromConfiguration();
//根据Configuration设置WAL模式
setWalModeFromConfiguration();
setJournalSizeLimit();
setAutoCheckpointInterval();
setLocaleFromConfiguration();
// Register custom functions.
final int functionCount = mConfiguration.customFunctions.size();
for (int i = 0; i < functionCount; i++) {
SQLiteCustomFunction function = mConfiguration.customFunctions.get(i);
nativeRegisterCustomFunction(mConnectionPtr, function);
}
}