Android将数据库保存到SD卡的实现

有时候为了需要,会将数据库保存到外部存储或者SD卡中(对于这种情况可以通过加密数据来避免数据被破解),比如一个应用支持多个数据,每个数据都需要有一个对应的数据库,并且数据库中的信息量特别大时,这显然更应该将数据库保存在外部存储或者SD卡中,因为RAM的大小是有限的;其次在写某些测试程序时将数据库保存在SD卡更方便查看数据库中的内容。

Android通过SQLiteOpenHelper创建数据库时默认是将数据库保存在’/data/data/应用程序名/databases’目录下的,只需要在继承SQLiteOpenHelper类的构造函数中传入数据库名称就可以了,但如果将数据库保存到指定的路径下面,都需要通过重写继承SQLiteOpenHelper类的构造函数中的context,因为:在阅读SQLiteOpenHelper.java的源码时会发现:创建数据库都是通过Context的openOrCreateDatabase方法实现的,,如果我们需要在指定的路径下创建数据库,就需要写一个类继承Context,并复写其openOrCreateDatabase方法,在openOrCreateDatabase方法中指定数据库存储的路径即可,下面为类SQLiteOpenHelper中getWritableDatabase和getReadableDatabase方法的源码,SQLiteOpenHelper就是通过这两个方法来创建数据库的。

/*** Create and/or open a database that will be used for reading and writing.* The first time this is called, the database will be opened and* {@link #onCreate}, {@link #onUpgrade} and/or {@link #onOpen} will be* called.** <p>Once opened successfully, the database is cached, so you can* call this method every time you need to write to the database.* (Make sure to call {@link #close} when you no longer need the database.)* Errors such as bad permissions or a full disk may cause this method* to fail, but future attempts may succeed if the problem is fixed.</p>** <p class="caution">Database upgrade may take a long time, you* should not call this method from the application main thread, including* from {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.** @throws SQLiteException if the database cannot be opened for writing* @return a read/write database object valid until {@link #close} is called*/public synchronized SQLiteDatabase getWritableDatabase() {if (mDatabase != null) {if (!mDatabase.isOpen()) {// darn! the user closed the database by calling mDatabase.close()mDatabase = null;} else if (!mDatabase.isReadOnly()) {return mDatabase; // The database is already open for business}}if (mIsInitializing) {throw new IllegalStateException("getWritableDatabase called recursively");}// If we have a read-only database open, someone could be using it// (though they shouldn't), which would cause a lock to be held on// the file, and our attempts to open the database read-write would// fail waiting for the file lock. To prevent that, we acquire the// lock on the read-only database, which shuts out other users.boolean success = false;SQLiteDatabase db = null;if (mDatabase != null) mDatabase.lock();try {mIsInitializing = true;if (mName == null) {db = SQLiteDatabase.create(null);} else {db = mContext.openOrCreateDatabase(mName, 0, mFactory, mErrorHandler);}int version = db.getVersion();if (version != mNewVersion) {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);success = true;return db;} finally {mIsInitializing = false;if (success) {if (mDatabase != null) {try { mDatabase.close(); } catch (Exception e) { }mDatabase.unlock();}mDatabase = db;} else {if (mDatabase != null) mDatabase.unlock();if (db != null) db.close();}}}/*** Create and/or open a database. This will be the same object returned by* {@link #getWritableDatabase} unless some problem, such as a full disk,* requires the database to be opened read-only. In that case, a read-only* database object will be returned. If the problem is fixed, a future call* to {@link #getWritableDatabase} may succeed, in which case the read-only* database object will be closed and the read/write object will be returned* in the future.** <p class="caution">Like {@link #getWritableDatabase}, this method may* take a long time to return, so you should not call it from the* application main thread, including from* {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.** @throws SQLiteException if the database cannot be opened* @return a database object valid until {@link #getWritableDatabase}*or {@link #close} is called.*/public synchronized SQLiteDatabase getReadableDatabase() {if (mDatabase != null) {if (!mDatabase.isOpen()) {// darn! the user closed the database by calling mDatabase.close()mDatabase = null;} else {return mDatabase; // The database is already open for business}}if (mIsInitializing) {throw new IllegalStateException("getReadableDatabase called recursively");}try {return getWritableDatabase();} catch (SQLiteException e) {if (mName == null) throw e; // Can't open a temp database read-only!Log.e(TAG, "Couldn't open " + mName + " for writing (will try read-only):", e);}SQLiteDatabase db = null;try {mIsInitializing = true;String path = mContext.getDatabasePath(mName).getPath();db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY,mErrorHandler);if (db.getVersion() != mNewVersion) {throw new SQLiteException("Can't upgrade read-only database from version " +db.getVersion() + " to " + mNewVersion + ": " + path);}onOpen(db);Log.w(TAG, "Opened " + mName + " in read-only mode");mDatabase = db;return mDatabase;} finally {mIsInitializing = false;if (db != null && db != mDatabase) db.close();}}

梦想从来不会选择人,它是上天赋予每个人构建未来蓝图的神奇画笔。

Android将数据库保存到SD卡的实现

相关文章:

你感兴趣的文章:

标签云: