android数据库创建,必须要继承SQLiteOpenHelper,通过情况下,db创建在默认位置,只需要在构造函数中,传入db name即可。
当调用getWritableDatabase()/getReadableDatabase()时候,均会synchronized调用getDatabaseLocked(boolean);
所有的DB初始化内容,均在getDatabaseLocked(boolean)中实现的。
如果项目需要修改DB放置位置,需要重写getWritableDatabase()/getReadableDatabase()及getDatabaseLocked(boolean);
故将对getDatabaseLocked(boolean)进行概要分析:
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.createInMemory(mOpenParamsBuilder.build());
}else {
final File filePath = mContext.getDatabasePath(mName);
SQLiteDatabase.OpenParams params = mOpenParamsBuilder.build();
try {
db = SQLiteDatabase.openDatabase(filePath, params);//依照传入参数,创建数据库的动作
// Keep pre-O-MR1 behavior by resetting file permissions to 660 setFilePermissionsForDb(filePath.getPath());
}catch (SQLException ex) {
if (writable) { throw ex; }
Log.e(TAG,"Couldn't open " + mName +" for writing (will try read-only):", ex);
params = params.toBuilder().addOpenFlags(SQLiteDatabase.OPEN_READONLY).build();
db = SQLiteDatabase.openDatabase(filePath, params);
}}
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);
}
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 {
if (version ==0) {//根据DB的version,来判断是否新建DB文件
onCreate(db);
}else {
if (version > mNewVersion) {//根据DB的version,来判断是否需要降级
onDowngrade(db, version, mNewVersion);
}else {//根据DB的version,来判断是否需要升级
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();}}}
android系统对数据库进行升降级,均会清除原始数据。如需在数据库升降级时,保留旧有数据,需要在SQLiteOpenHelper中重写onDowngrade()/onUpgrade().
下面为SQLiteOpenHelper中onDowngrade()/onUpgrade()的源码使用说明: