Android getReadableDatabase() 和 getWritableDatabase()分析对比
AndroidgetReadableDatabase()和getWritableDatabase()分析对比
Android使用getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例。(getReadableDatabase()方法中会调用getWritableDatabase()方法)
其中getWritableDatabase()方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用的是getWritableDatabase()方法就会出错。
getReadableDatabase()方法则是先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。如果该问题成功解决,则只读数据库对象就会关闭,然后返回一个可读写的数据库对象。
源码如下:
/**
*Createand/oropenadatabasethatwillbeusedforreadingandwriting.
*Onceopenedsuccessfully,thedatabaseiscached,soyoucancallthis
*methodeverytimeyouneedtowritetothedatabase.Makesuretocall
*{@link#close}whenyounolongerneedit.
*
*Errorssuchasbadpermissionsorafulldiskmaycausethisoperation
*tofail,butfutureattemptsmaysucceediftheproblemisfixed.
*
*@throwsSQLiteExceptionifthedatabasecannotbeopenedforwriting
*@returnaread/writedatabaseobjectvaliduntil{@link#close}iscalled
*/
publicsynchronizedSQLiteDatabasegetWritableDatabase(){
if(mDatabase!=null&&mDatabase.isOpen()&&!mDatabase.isReadOnly()){
returnmDatabase;//Thedatabaseisalreadyopenforbusiness
}
if(mIsInitializing){
thrownewIllegalStateException("getWritableDatabasecalledrecursively");
}
//Ifwehavearead-onlydatabaseopen,someonecouldbeusingit
//(thoughtheyshouldn't),whichwouldcausealocktobeheldon
//thefile,andourattemptstoopenthedatabaseread-writewould
//failwaitingforthefilelock.Topreventthat,weacquirethe
//lockontheread-onlydatabase,whichshutsoutotherusers.
booleansuccess=false;
SQLiteDatabasedb=null;
if(mDatabase!=null)mDatabase.lock();
try{
mIsInitializing=true;
if(mName==null){
db=SQLiteDatabase.create(null);
}else{
db=mContext.openOrCreateDatabase(mName,0,mFactory);
}
intversion=db.getVersion();
if(version!=mNewVersion){
db.beginTransaction();
try{
if(version==0){
onCreate(db);
}else{
onUpgrade(db,version,mNewVersion);
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
}finally{
db.endTransaction();
}
}
onOpen(db);
success=true;
returndb;
}finally{
mIsInitializing=false;
if(success){
if(mDatabase!=null){
try{mDatabase.close();}catch(Exceptione){}
mDatabase.unlock();
}
mDatabase=db;
}else{
if(mDatabase!=null)mDatabase.unlock();
if(db!=null)db.close();
}
}
}
/**
*Createand/oropenadatabase.Thiswillbethesameobjectreturnedby
*{@link#getWritableDatabase}unlesssomeproblem,suchasafulldisk,
*requiresthedatabasetobeopenedread-only.Inthatcase,aread-only
*databaseobjectwillbereturned.Iftheproblemisfixed,afuturecall
*to{@link#getWritableDatabase}maysucceed,inwhichcasetheread-only
*databaseobjectwillbeclosedandtheread/writeobjectwillbereturned
*inthefuture.
*
*@throwsSQLiteExceptionifthedatabasecannotbeopened
*@returnadatabaseobjectvaliduntil{@link#getWritableDatabase}
*or{@link#close}iscalled.
*/
publicsynchronizedSQLiteDatabasegetReadableDatabase(){
if(mDatabase!=null&&mDatabase.isOpen()){
returnmDatabase;//Thedatabaseisalreadyopenforbusiness
}
if(mIsInitializing){
thrownewIllegalStateException("getReadableDatabasecalledrecursively");
}
try{
returngetWritableDatabase();
}catch(SQLiteExceptione){
if(mName==null)throwe;//Can'topenatempdatabaseread-only!
Log.e(TAG,"Couldn'topen"+mName+"forwriting(willtryread-only):",e);
}
SQLiteDatabasedb=null;
try{
mIsInitializing=true;
Stringpath=mContext.getDatabasePath(mName).getPath();
db=SQLiteDatabase.openDatabase(path,mFactory,SQLiteDatabase.OPEN_READONLY);
if(db.getVersion()!=mNewVersion){
thrownewSQLiteException("Can'tupgraderead-onlydatabasefromversion"+
db.getVersion()+"to"+mNewVersion+":"+path);
}
onOpen(db);
Log.w(TAG,"Opened"+mName+"inread-onlymode");
mDatabase=db;
returnmDatabase;
}finally{
mIsInitializing=false;
if(db!=null&&db!=mDatabase)db.close();
}
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!