手动集成sqlite的方法

发布于:2025-03-21 ⋅ 阅读:(20) ⋅ 点赞:(0)

注意到sqlite有backup方法(https://www.sqlite.org/backup.html)。

也注意到android中sysroot下,没有sqlite3的库,也没有相关头文件。

如果要使用 sqlite 的backup,那么就需要手动集成sqlite代码到项目中。可以如下操作:


以下是手动将 SQLite 源码集成到 Android NDK 项目中的完整方案(基于 Android.mk),适用于需要 定制 SQLite 版本静态链接 的场景:


步骤 1:获取 SQLite 源码

  1. 下载合并版源码
    访问 SQLite 官网下载页,获取 合并版源码(文件名类似 sqlite-amalgamation-3420000.zip),解压后包含:

    • sqlite3.c:所有核心代码的合并文件
    • sqlite3.h:主头文件
    • sqlite3ext.h:扩展头文件(可选)
    • shell.c:命令行工具(无需此文件
  2. 放置源码到项目
    sqlite3.csqlite3.h 复制到项目的 jni 目录:

    project-root/
    └── app/
        └── src/main/
            └── jni/
                ├── sqlite3.c
                ├── sqlite3.h
                ├── your-code.c
                ├── Android.mk
                └── Application.mk
    

步骤 2:配置 Android.mk

LOCAL_PATH := $(call my-dir)

# 编译 SQLite 为静态库
include $(CLEAR_VARS)
LOCAL_MODULE := sqlite3
LOCAL_SRC_FILES := sqlite3.c
LOCAL_CFLAGS := -DSQLITE_ENABLE_BACKUP \  # 启用备份功能
                -DSQLITE_DEFAULT_MEMSTATUS=0 \  # 禁用内存统计(节省内存)
                -DSQLITE_OMIT_DEPRECATED  # 移除废弃API
include $(BUILD_STATIC_LIBRARY)

# 编译主模块
include $(CLEAR_VARS)
LOCAL_MODULE := your-module-name  # 与Java中System.loadLibrary()一致
LOCAL_SRC_FILES := your-code.c
LOCAL_STATIC_LIBRARIES := sqlite3  # 链接静态库
LOCAL_LDLIBS := -llog  # 如果需要Android日志
include $(BUILD_SHARED_LIBRARY)

关键配置说明

1. SQLite 编译选项

通过 LOCAL_CFLAGS 定制功能:

-DSQLITE_ENABLE_BACKUP       # 必须开启备份API
-DSQLITE_THREADSAFE=1        # 线程安全模式(默认)
-DSQLITE_ENABLE_FTS5         # 启用全文搜索FTS5
-DSQLITE_USE_URI=1           # 支持URI格式文件名
2. 优化选项
-DSQLITE_DEFAULT_MEMSTATUS=0  # 关闭内存统计,减少内存占用
-DSQLITE_OMIT_DEPRECATED      # 移除废弃函数
-DNDEBUG=1                    # 关闭调试断言
3. ABI 兼容性

Application.mk 中指定支持的 CPU 架构:

APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
APP_OPTIM := release  # 开启编译器优化

步骤 3:在 C 代码中使用 SQLite

#include <jni.h>
#include <sqlite3.h>  // 使用本地源码

JNIEXPORT void JNICALL
Java_com_example_YourClass_method(JNIEnv *env, jobject thiz) {
    sqlite3 *db;
    int rc = sqlite3_open(":memory:", &db);  // 使用内存数据库
    
    // 执行备份操作
    sqlite3_backup *backup = sqlite3_backup_init(dest_db, "main", src_db, "main");
    // ... 备份逻辑 ...
}

验证是否成功

1. 编译检查

运行 ndk-build 时观察输出:

$ ndk-build
[armeabi-v7a] Compile thumb  : sqlite3 <= sqlite3.c
[armeabi-v7a] StaticLibrary  : libsqlite3.a
[armeabi-v7a] Compile thumb  : your-module <= your-code.c
[armeabi-v7a] SharedLibrary  : libyour-module.so
2. 运行时日志

在代码中添加版本查询:

__android_log_print(ANDROID_LOG_DEBUG, "SQLite", "Version: %s", sqlite3_libversion());

预期输出:

D/SQLite: Version: 3.42.0  # 与下载的源码版本一致

常见问题解决

1. 头文件找不到 (sqlite3.h: No such file)
  • 确保 sqlite3.hsqlite3.c 位于 jni 目录
  • 检查 LOCAL_SRC_FILES 是否包含 sqlite3.c
2. 功能未生效(如 sqlite3_backup_init 不存在)
  • 确认编译时添加了 -DSQLITE_ENABLE_BACKUP
  • 检查 SQLite 源码版本是否支持该功能

手动集成的优缺点

优点 缺点
版本可控:可自由升级/降级 SQLite 增大 APK 体积(约 2-3 MB)
功能定制:启用/禁用特定功能 需自行处理安全更新
无系统依赖:兼容所有 Android 版本 编译时间增加