Android NDK用にSQLiteをビルドして利用する

test105_01.png
今回はオープンソースのデータベース「SQLite」をAndroid NDKから呼び出して利用してみる。

まずhttp://www.sqlite.org/ download.htmlからSQLiteのソースコードをダウンロードする。利用したバージョンはSQLite 3.7.4だ。

test105_02.png
次にEasyProjectGenerator for Android Ver 1.00を利用してAndroid NDKプロジェクトを生成、Eclipseに取り込む。

test105_03.png
そしてプロジェクトフォルダのjniフォルダの下に「sqlite」というフォルダを作り、中に先ほどダウンロードしたSQLiteのソースコードを一式解凍する。

test105_04.png
さらに自動生成されていたソースコードとmakefileを「test105」というフォルダを作り、その中へ移動する。

test105_05.png
これでプロジェクトフォルダ内が図のようになった。

test105_06.png
ここでjniフォルダ直下にAndroid.mkファイルを新規作成する。

test105_07.png jniフォルダ直下にAndroid.mkファイルの中に1行追加。サブフォルダのmakefileを検索してビルドされるようにした。
include $(call all-subdir-makefiles)

test105_08.png 次にsqliteフォルダ直下にAndroid.mkファイルを新規作成し、内容を編集する。
このmakefileはAndroidプロジェクトのhttp://code.google.com/ p/rowboat/内で使われていたものを改変した。
#
# from rowboat-external-sqlite-master and modified
#

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES := sqlite3.c

ifneq ($(TARGET_ARCH),arm)
LOCAL_LDLIBS += -lpthread -ldl
endif

LOCAL_CFLAGS += -DHAVE_USLEEP=1 -DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576 -DSQLITE_THREADSAFE=1 -DNDEBUG=1 -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 -DSQLITE_DEFAULT_AUTOVACUUM=1 -DSQLITE_TEMP_STORE=3 -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_BACKWARDS -DSQLITE_ENABLE_POISON -Dfdatasync=fsync

ifneq ($(TARGET_SIMULATOR),true)
LOCAL_SHARED_LIBRARIES := libdl
endif

LOCAL_MODULE:= libsqlite
#new sqlite 3.5.6 no longer support external allocator
#LOCAL_CFLAGS += -DSQLITE_OMIT_MEMORY_ALLOCATION
LOCAL_C_INCLUDES += $(call include-path-for, system-core)/cutils
LOCAL_SHARED_LIBRARIES += liblog \
            libicuuc \
            libicui18n \
            libutils

# include android specific methods
LOCAL_WHOLE_STATIC_LIBRARIES := libsqlite3_android

include $(BUILD_SHARED_LIBRARY)

test105_09.png 次にJNIにより実行される関数でSQLiteが利用されるようにする。
#include <string.h>
#include <jni.h>

#include "../sqlite/sqlite3.h"

jstring
Java_com_Test105_Test105Act_stringFromJNI(JNIEnv* env,jobject thiz)
{
	char	pszRet[256];
	strcpy(pszRet,"Failed.");

	sqlite3 *db;
	int rc = sqlite3_open("/sdcard/a.db", &db);
	sqlite3_stmt *st;

	rc = sqlite3_prepare(db, "CREATE TABLE test(id INTEGER PRIMARY KEY,name TEXT);", -1, &st, NULL);
	rc = sqlite3_step(st);
	rc = sqlite3_finalize(st);

	rc = sqlite3_prepare(db, "INSERT INTO test(name) VALUES (?);", -1, &st, NULL);
	sqlite3_bind_text(st, 1, "abcdef", -1, SQLITE_STATIC);
	rc = sqlite3_step(st);
	rc = sqlite3_finalize(st);

	rc = sqlite3_prepare(db, "SELECT name FROM test", -1, &st, NULL);
	while((rc = sqlite3_step(st)) == SQLITE_ROW)
	{
		char* pszName = (char*)sqlite3_column_text(st, 0);
		strcpy(pszRet,pszName);
		break;
	}
	sqlite3_finalize(st);

	sqlite3_close(db);

	return (*env)->NewStringUTF(env, pszRet);
}

test105_10.png そして共有ライブラリとしてSQLiteが読み込まれるようにAndroid.mkを編集する。
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := Test105jni
LOCAL_SRC_FILES := Test105jni.c

LOCAL_SHARED_LIBRARIES := libsqlite

include $(BUILD_SHARED_LIBRARY)

test105_11.png
これでndk-buildによりネイティブコードをビルドする。

test105_12.png
そしてプロジェクトをAndroidエミュレーターで実行。

test105_13.png
これで正常に動いた。

test105_14.png
EclipseのDDMSから仮想SDカード内にSQLiteが作成したデータベースファイルも確認できる。




プロジェクトファイルをダウンロード


カテゴリー「android」 のエントリー