最近在给公司开发NDK相关的东西,需要持久化的存储一些数据。
刚开始是想用文件来存储的,后来发现文件不方便检索,就想到了使用sqlite。
sqlite操作起来比较简单,可是在NDK下面开发就没有经验了。
百度之后发现,可以使用静态库和动态库两种方法来加载sqlite库,进行sqlite的操作。
两种方法的优缺点如下:
1. 静态库就是把库文件编译到代码中,这样编译出的文件相比于动态库要大点,但是操作比较简单。
2. 动态库就是在程序运行的时候加载需要的库文件,这样编译出来的文件比较小,也可以方便库的复用。但是前期配置比较复杂。
百度出来的大部分都是动态库的方式,可能是我水平不行,试了半天一直不成功。后来在stackoverflow(http://stackoverflow.com/questions/5523067/sqlite-with-android-ndk)上发现一个静态库的方式,使用起来比较简单,下面简单介绍一下。
一、 静态库方式
1. 上官网下载sqlite3源码
http://www.sqlite.org/download.html
2. 将sqlite3.c 和 sqlite3.h 拷贝到jni文件夹中
3. Android.mk文件中LOCAL_SRC_FILES
加上 sqlite3.c
4. 代码中使用的时候#include "sqlite3.h" 即可。
代码如下:
sqliteTest.c
#include<stdio.h> #include<string.h> #include "mydebug.h" #include "sqlite3.h" static int callback(void *NotUsed, int argc, char **argv, char **azColName) { int i; for (i = 0; i < argc; ++i) { LOGE("mydebug", "%s = %s,", azColName[i], argv[i] ? argv[i] : "NULL"); } LOGE("mydebug", " "); return 0; } int sqlite_test(char *database_name) { sqlite3 *db; char *sql, *errMsg; int rv; rv = sqlite3_open(database_name, &db); if(rv) { LOGE("mydebug","sqlite open error %s ", sqlite3_errmsg(db)); sqlite3_close(db); } sql = "CREATE TABLE IF NOT EXISTS parameter (" "id INTEGER PRIMARY KEY NOT NULL," "name TEXT NOT NULL" ");"; rv = sqlite3_exec(db, sql, callback, 0, &errMsg); if(rv != SQLITE_OK) { LOGE("mydebug", "sqlite exec error %s, sql = %s ", errMsg, sql); return -1; } else { LOGE("mydebug", "sqlite create table success"); } sql = "INSERT INTO parameter (id, name) VALUES " "(4, 'end')"; rv = sqlite3_exec(db, sql, callback, 0, &errMsg); LOGE("mydebug", "insert into rv = %d", rv); if(rv != SQLITE_OK) { LOGE("mydebug", "sqlite exec error %s, sql = %s ", errMsg, sql); return -1; } else { LOGE("mydebug", "sqlite insert into success"); } sql = "SELECT * FROM parameter "; rv = sqlite3_exec(db, sql, callback, 0, &errMsg); if(rv != SQLITE_OK) { LOGE("mydebug", "sqlite exec error %s, sql = %s ", errMsg, sql); return -1; } else { LOGE("mydebug", "sqlite select success"); return 0; } sqlite3_close(db); return 0; }
调用:
JNIEXPORT jstring JNICALL Java_com_example_q6jnitest_Jni_SqliteTest(JNIEnv * env,jclass obj) { LOGE("mydebug", "start "); char database_name[] = "/sdcard/test.db"; sqlite_test((char *)database_name); return env->NewStringUTF("sqlite success"); }
程序运行之后就可以在/sdcard文件夹下找到数据库文件,可以用adb.exe将数据库文件拷贝到电脑上来查看。
adb pull /sdcard/test.db C:UsersadministereDesktop