是否可以在 apk 中获得对 sqlite 数据库的只读访问权限?

发布于 2024-11-04 17:19:02 字数 266 浏览 0 评论 0原文

可能的重复:
如何将现有数据库放入 .apk 文件中?

是否可以获得对 apk 所在的 sqlite 数据库的只读访问权限?如果可以从 apk 内以只读目的访问数据库,我不想复制数据库。

Possible Duplicate:
How to put existing database in the .apk file?

Is it possible to obtain read-only access to an sqlite database located with an apk? I don't want to duplicate the database if it is possible to access it for read-only purposes from within the apk.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

逐鹿 2024-11-11 17:19:02

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

android-staticdb 是一个 Android 库,允许对应用程序 < 中包含的 SQLite 数据库进行只读访问代码>.apk 文件。这对于需要附带大量静态数据的应用程序(例如离线维基百科阅读器)来说是理想的选择。

它的工作原理是通过本机 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 以传递 标记到 标记...

注意:

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

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.

别把无礼当个性 2024-11-11 17:19:02

正如这个答案中提到的 从资产中加载大于 1M 的文件文件夹

如果资源未压缩,系统可以对文件数据进行内存映射
并使用Linux虚拟内存分页系统进行拉入或丢弃
4K 块(视情况而定)。

如果这是真的,则可以将未压缩的数据库存储到 APK(使用一些扩展名,如 mp3 来保持文件未压缩)并直接从 APK 读取它。这只是我的猜测,但我不太确定实施情况。

对于 Android 2.3 及更高版本,您可以使用 NDK http: //groups.google.com/group/android-ndk/browse_thread/thread/30b9f5abf48347a0/ef62db9a18646b1d

As mentioned in this answer Load files bigger than 1M from assets folder

If the asset is uncompressed, the system can memory-map the file data
and use the Linux virtual memory paging system to pull in or discard
4K chunks as appropriate.

If that's true, one could store uncompressed database to APK (using some of extensions like mp3 to keep file uncopressed) and read it directly from APK. That's only my speculations, I'm not really sure about implementation though.

For Android 2.3 and newer you could use Native Access using NDK http://groups.google.com/group/android-ndk/browse_thread/thread/30b9f5abf48347a0/ef62db9a18646b1d .

谁人与我共长歌 2024-11-11 17:19:02

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

据我所知,Android 是一个 Linux 发行版,其中每个 .apk 都是由一个单独的用户帐户安装的,没有一个是 root 帐户。因此,应用空间被有效地划分。

No, the apk must have an interface for you to pull data - which can be exposed with an Android service.

To my knowledge, Android is a Linux distribution where each .apk is installed as/by a separate user account, none of which are root. Therefore, the application spaces are effectively partitioned.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文