是否有可能获得对位于apk的sqlite数据库的只读访问权限?如果可以从apk中以只读方式访问数据库,我不想复制数据库。
答案 0 :(得分:11)
我刚开始为Android开发,并且惊讶地发现捆绑静态数据库不容易做。所以我做了唯一合理的事情:创建了一个可以做到这一点的库。
android-staticdb是一个Android库,允许对应用程序的.apk
文件中包含的SQLite数据库进行只读访问。这对于需要附带大量静态数据的应用程序(例如离线维基百科阅读器)非常理想。
它的工作原理是使用来自本机C代码的SQLite库注册一个新的“虚拟文件系统”层,该层能够拦截SQLite发出的文件系统调用。因为每个VM进程只有一个SQLite库副本,所以我们实际上最终会拦截任何应用程序在与我们相同的进程中进行的任何SQLite调用!
在正常操作中,我们的VFS层只是代理所有对“默认”的调用
VFS,它只使用open()和read()来访问常规数据库文件。但
当遇到匹配*.apk!filename
模式的特殊文件名时,
我们的VFS抓住了控制权。使用zlib和minizip,它会打开.apk
文件和
在里面查找数据库文件;然后它将读取此文件的块
满足来自SQLite的任何read()
个请求。
通过这种方式,应用程序可以继续使用该标准 Android数据库API。
使用示例:
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'...
}
}
您返回一个标准的SQLiteDatabase对象,唯一的限制是它不支持写入。 (显然!)
请注意,除非数据库存储在您的.apk
中而不进行压缩,否则这将失败。使用aapt -0
命令添加SQLite数据库,或修改build.xml
以将<nocompress extension="db" />
标记传递给<aapt>
标记...
我刚刚写完这篇文章,到目前为止只进行了非常基本的测试。错误报告将不胜感激。
答案 1 :(得分:2)
如本回答Load files bigger than 1M from assets folder
所述如果资产未压缩,系统可以对文件数据进行内存映射 并使用Linux虚拟内存分页系统来拉入或丢弃 适当的4K块。
如果这是真的,可以将未压缩的数据库存储到APK(使用一些扩展,如mp3以保持文件不被压缩)并直接从APK读取。这只是我的推测,但我不确定实现。
对于Android 2.3及更新版本,您可以使用NDK http://groups.google.com/group/android-ndk/browse_thread/thread/30b9f5abf48347a0/ef62db9a18646b1d进行本机访问。
答案 2 :(得分:1)
不,apk必须有一个界面供您拉取数据 - 可以通过Android服务公开。
据我所知,Android是一个Linux发行版,其中每个.apk作为/由一个单独的用户帐户安装,其中没有一个是root用户。因此,应用程序空间被有效地分区。