Recently encountered the need to load the existing path under the (SD card) DB problem, find a bit of information, the following is the solution, for reference only (reprinted from EoE):
Sqliteopenhelper is an Android framework that provides us with a very good database of open, upgraded and Closed tool classes. However, this tool class will automatically create the db file into the "/data/data/com.*.* (package name)/" directory, which may be related to the design of the Android file system.
However, in the actual combat process, we may have a variety of reasons for the need to customize the DB file path (such as the large size of the db file to the SD card more secure, etc.), I believe many people have encountered this demand, there are many solutions on the Internet, Most of these methods are to abandon the Android framework to provide us with the Sqliteopenhelper class, write your own DBHelper class to complete the custom path of the database open close and so on. Doing so can solve the problem, but it is not the best way to write the DBHelper reliability and functionality naturally difficult and Google Giants phase.
In this paper, we propose a method to solve the problem of custom DB path by inheriting and adding code and reusing Sqliteopenhelper code.
First, let's analyze the source code of Sqliteopenhelper. Both Getreadabledatabase () and Getwritabledatabase () are internally called getdatabaselocked (). The source code of getdatabaselocked () is easy to understand and the analysis learns that:
- If opened as read-only, the path to the db file is obtained by Mcontext.getdatabasepath (mname) and the database is opened directly using Sqlitedatabase.opendatabase ();
- If open in read and write mode, is through Mcontext.openorcreatedatabase (Mname, menablewriteaheadlogging? context.mode_enable_write_ahead_logging:0, MFactory, Merrorhandler) Open or create a database.
So we need to change the behavior of Mcontext. The Android framework provides a Contextwrapper class, which is a proxy for the context, which can be inherited to change the behavior of the context, so we inherit Contextwrapper, the code is as follows:
Class Custompathdatabasecontext extends contextwrapper{
Private String Mdirpath;
Public Custompathdatabasecontext (Context base, String Dirpath) {
Super (base);
This.mdirpath = Dirpath;
}
@Override
Public File Getdatabasepath (String name) {
File result = new file (Mdirpath + file.separator + name);
if (!result.getparentfile (). exists ()) {
Result.getparentfile (). Mkdirs ();
}
return result;
}
@Override
Public sqlitedatabase openorcreatedatabase (String name, int mode, Cursorfactory Factory) {
Return Sqlitedatabase.openorcreatedatabase (Getdatabasepath (name), factory);
}
@Override
Public sqlitedatabase openorcreatedatabase (String name, int mode, Cursorfactory factory, Databaseerrorhandler ErrorHandler) {
Return Sqlitedatabase.openorcreatedatabase (Getdatabasepath (name). GetAbsolutePath (), factory, ErrorHandler);
}
}
The above code is very simple, it is not necessary to explain it, and then we inherit the sqliteopenhelper when this can be written:
Class Yourdbhelper extends sqliteopenhelper{
Public Yourdbhelper (Context context, String name, Cursorfactory factory,
int version) {
Super (new Custompathdatabasecontext (Context, Getdirpath ()), name, Factory, version);
}
/**
* Get the path of the db file on the SD card
* @return
*/
private static String Getdirpath () {
TODO here returns the absolute path of the folder that holds the DB
Return "";
}
@Override
public void OnCreate (Sqlitedatabase db) {
}
@Override
public void Onupgrade (sqlitedatabase db, int oldversion, int newversion) {
}
}
In this way, we can either customize the DB file path, or reuse sqliteopenhelper very useful features ~
It is also important to note that some applications may be a DB file with a built-in table in assets, and the application runtime will first determine if the DB file exists and if it does not, copy it from assets to the custom path. This is usually done on the PC side using Sqlitespy and other tools to write SQL build tables, the small partners using this method do not forget to do PRAGMA schema_version = 1 This SQL (of course, the version number depends on your needs), Otherwise sqliteopenhelper will trigger OnCreate ~ See Sqliteopenhelper when trigger OnCreate of the source will understand what's going on ~
Solve DB problems with SQLite open existing path