I've just started developing for Android, and was surprised to discover that bundling a static database is not easy to do. So I did the only reasonable thing: created a library which does just that.
android-staticdb is an Android library to allow read-only access to SQLite databases contained in an application's .apk
file. This is ideal for apps which need to ship with a large quantity of static data (e.g. an offline Wikipedia reader).
It works by registering a new "virtual filesystem" layer with the SQLite library from native C code, which is able to intercept the filesystem calls made by SQLite. Because there is only one copy of the SQLite library per VM process, we actually end up intercepting any SQLite calls made by any application in the same process as us!
In normal operation, our VFS layer simply proxies all calls to the "default"
VFS, which just uses open() and read() to access regular database files. But
when a special filename matching the *.apk!filename
pattern is encountered,
our VFS grabs control. Using zlib and minizip, it opens the .apk
file and
looks inside for the database file; it will then read chunks of this file to
satisfy any read()
requests from SQLite.
By doing this in this manner, applications can continue to use the standard
Android database APIs.
Example usage:
import android.database.sqlite.SQLiteDatabase;
import kiwidrew.staticdb.StaticDatabase;
public class BlahBlah extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SQLiteDatabase db = StaticDatabase.openDatabase(this, "assets/foobar.db");
// Do normal database stuff with 'db'...
}
}
You get back a standard SQLiteDatabase object, with the only restriction being that it doesn't support writing. (Obviously!)
Note that this will fail unless the database is stored in your .apk
without compression. Add the SQLite database using the aapt -0
command or modify your build.xml
to pass the <nocompress extension="db" />
flag to the <aapt>
tag...
Note:
I've literally just finished writing this, and have only done very basic testing so far. Bug reports would be appreciated.