【问题标题】:Is it possible to obtain read-only access to an sqlite database in an apk? [duplicate]是否可以在 apk 中获得对 sqlite 数据库的只读访问权限? [复制]
【发布时间】:2011-08-17 22:46:31
【问题描述】:

可能重复:
How to put existing database in the .apk file?

是否可以获得对位于 apk 的 sqlite 数据库的只读访问权限?如果可以从 apk 中出于只读目的访问它,我不想复制数据库。

【问题讨论】:

    标签: android sqlite


    【解决方案1】:

    我刚刚开始为 Android 开发,并惊讶地发现捆绑静态数据库不容易。所以我做了唯一合理的事情:创建了一个库来做到这一点。

    android-staticdb 是一个 Android 库,允许对包含在应用程序的 .apk 文件中的 SQLite 数据库进行只读访问。这非常适合需要附带大量静态数据的应用程序(例如离线维基百科阅读器)。

    它通过从本地 C 代码向 SQLite 库注册一个新的“虚拟文件系统”层来工作,该库能够拦截 SQLite 进行的文件系统调用。因为每个 VM 进程只有一个 SQLite 库副本,所以我们实际上最终会拦截 any 应用程序在与我们相同的进程中进行的任何 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> 标记...

    注意:

    我刚刚写完这篇文章,到目前为止只进行了非常基本的测试。错误报告将不胜感激。

    【讨论】:

      【解决方案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 使用 Native Access。

      【讨论】:

        【解决方案3】:

        不,apk 必须有一个接口供您提取数据 - 可以通过 Android 服务公开。

        据我所知,Android 是一个 Linux 发行版,其中每个 .apk 都作为/由单独的用户帐户安装,这些帐户都不是 root。因此,应用空间得到了有效的划分。

        【讨论】:

        • 是的,但我的意思是我想从 apk 自己的应用程序空间中打开数据库,而不必先复制出来。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-25
        • 1970-01-01
        • 1970-01-01
        • 2012-10-22
        • 2018-08-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多