上一篇:我们学习了如何用AndroidStudio和SQLiteExpertPro方便的查看SQLite数据库。
本篇我们开始学习,SQLiteDatabase的基本用法:
我们可以通过SQLiteOpenHelper获取一个SQLiteDataBase:
具体方法如下:
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()) {
// Darn! The user closed the database by calling mDatabase.close().
mDatabase = null;
} else if (!writable || !mDatabase.isReadOnly()) {
// The database is already open for business.
return mDatabase;
}
}
if (mIsInitializing) {
throw new IllegalStateException("getDatabase called recursively");
}
SQLiteDatabase db = mDatabase;
try {
mIsInitializing = true;
if (db != null) {
if (writable && db.isReadOnly()) {
db.reopenReadWrite();
}
} else if (mName == null) {
db = SQLiteDatabase.create(null);
} else {
try {
if (DEBUG_STRICT_READONLY && !writable) {
final String path = mContext.getDatabasePath(mName).getPath();
db = SQLiteDatabase.openDatabase(path, mFactory,
SQLiteDatabase.OPEN_READONLY, mErrorHandler);
} else {
db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ?
Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0,
mFactory, mErrorHandler);
}
} catch (SQLiteException ex) {
if (writable) {
throw ex;
}
Log.e(TAG, "Couldn't open " + mName
+ " for writing (will try read-only):", ex);
final String path = mContext.getDatabasePath(mName).getPath();
db = SQLiteDatabase.openDatabase(path, mFactory,
SQLiteDatabase.OPEN_READONLY, mErrorHandler);
}
}
onConfigure(db);
final int version = db.getVersion();
if (version != mNewVersion) {
if (db.isReadOnly()) {
throw new SQLiteException("Can't upgrade read-only database from version " +
db.getVersion() + " to " + mNewVersion + ": " + mName);
}
db.beginTransaction();
try {
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);
if (db.isReadOnly()) {
Log.w(TAG, "Opened " + mName + " in read-only mode");
}
mDatabase = db;
return db;
} finally {
mIsInitializing = false;
if (db != null && db != mDatabase) {
db.close();
}
}
}
主要我们看到:
SQLiteDatabase.openDatabase(path, mFactory,
SQLiteDatabase.OPEN_READONLY, mErrorHandler);
该方法返回了一个SQLiteDatabase
我们再看一下opendatabase方法。
opendatabase:
public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags,
DatabaseErrorHandler errorHandler) {
SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler);
db.open();
return db;
}i
open方法:
private void open() {
try {
try {
openInner();
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
openInner();
}
} catch (SQLiteException ex) {
Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex);
close();
throw ex;
}
}
private void openInner() {
synchronized (mLock) {
assert mConnectionPoolLocked == null;
mConnectionPoolLocked = SQLiteConnectionPool.open(mConfigurationLocked);
mCloseGuardLocked.open("close");
}
synchronized (sActiveDatabases) {
sActiveDatabases.put(this, null);
}
}
如何管理 mConnectionPoolLocked呢?
原来SQLiteDatabase使用了一个叫SQLiteSession来管理和使用该SQLiteConnectionPool。
上源码:
private final ThreadLocal mThreadSession = new ThreadLocal() {
@Override
protected SQLiteSession initialValue() {
return createSession();
}
};
SQLiteSession getThreadSession() {
return mThreadSession.get(); // initialValue() throws if database closed
}
SQLiteSession createSession() {
final SQLiteConnectionPool pool;
synchronized (mLock) {
throwIfNotOpenLocked();
pool = mConnectionPoolLocked;
}
return new SQLiteSession(pool);
}
可以看到:SQLiteDatabase使用ThreadLocal来定义了一个SQLiteSession,这样可以保证单线程中只有一个ThreadSession。
而重写了initialValue方法:保证每次get的时候会new 一个SQLiteSession,并传入mConnectionPoolLocked。这样多个ThreadSession其实是共享了一个线程池。
(可以猜到:SQLiteDatabase应该在执行SQL时候都会使用这个getThreadSession来 获取SQLiteConnection的。)
这时候就需要知道SQLiteSession的工作原理了。
下一篇:Android学习笔记-数据库开发-4:SQLiteDataBase基本用法(3):SQLiteSession的工作原理