標籤:des android style blog class c
本例採用jsoncpp-src-0.6.0-rc2-amalgamation.tar
java調用語句
int id = 1001;
String name = "Kevin";
String result = system.toBuildJson(id, name);
Log.i(TAG,String.format("Id:%1$d,Name:%2$s,The json formated string:%3$s", id,name,result));
單寫一個類來管理native函數如下
package com.mjson;
public class system {
static {
System.loadLibrary("jsoncpp");
System.loadLibrary("system");
}
public static native String toBuildJson(int id,String name);
}
配置好ndk和cywin(詳見http://blog.csdn.net/pengchua/article/details/7582949
http://my.oschina.net/lifj/blog/177087)
在cywin控制視窗cd到自己的項目下,如 /cygdrive/d/jdk/work/mJson/
javah -classpath bin/classes -d jni com.mJson.system
產生.h介面檔案
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <android/log.h>
#include "json/json.h"
#define LOG_TAG "system"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
/* Header for class com_mjson_system */
#ifndef _Included_com_mjson_system
#define _Included_com_mjson_system #ifdef __cplusplus
#endif
/* * Class: com_mjson_system * Method: toBuildJson * Signature: (ILjava/lang/String;)Ljava/lang/String; */
JNIEXPORT jstring JNICALL Java_com_mjson_system_toBuildJson (JNIEnv *, jclass, jint, jstring);
#ifdef __cplusplus
#endif #endif
本來對於JNIEXPORT jstring JNICALL Java_com_...這個函數需要entends “c”{}包含,用於標識是c實現,便於編譯成動態庫,但是
由於我將函數的實現挪到了system.cpp中實現,所以此處去掉,將此加到system.cpp中,不然編譯時間會報衝突錯誤
systm.cpp如下
#include "com_mjson_system.h"
extern "C" {
JNIEXPORT jstring JNICALL Java_com_mjson_system_toBuildJson
(JNIEnv* env, jobject thiz,jint id,jstring name){
jboolean isCopy = 0;
const char* c_name = env->GetStringUTFChars(name, &isCopy);
LOGD("on calling,id:%d,name:%s",id,c_name);
// to build a json object with id and name
Json::Value user;
user["id"] = id;
user["name"] = c_name;
const char* json_str = user.toStyledString().c_str();
jstring result = env->NewStringUTF(json_str);
env->ReleaseStringUTFChars(name,c_name);
return result;
}
}
在jni下建立Application
# it is needed for ndk-r5
#APP_STL := stlport_static
APP_STL := gnustl_static
在jni下建立Android.mk檔案
在Makefile時注意路徑
1、JsonCpp用到了stl的exception,所以如果你在android的編譯系統的Application檔案中指定STL庫路徑時,如果使用: APP_STL := stlport_static,那麼就無法通過編譯。需要改成:APP_STL := gnustl_static
2、jsoncpp的make file。注意LOCAL_CPPFLAGS := -DJSON_IS_AMALGAMATION -fexceptions 這一行。宏定義JSON_IS_AMALGAMATION告訴jsoncpp是amalgamation版本,即是我們剛才下載的版本。-fexceptions則開啟exception應用。
3、我們的測試程式的make file。注意LOCAL_C_INCLUDES := $(LOCAL_PATH)/soncpp這一行,我們指定了標頭檔的地址為,當前路徑(即$project/jni/test/)的上一級的jsoncpp檔案夾,即$project/jni/jsoncpp/,這樣在使用中我們需要inlcude的就是 "json/json.h"。
- LOCAL_LDLIBS := -L$(call host-path, $(LOCAL_PATH)/../../libs/armeabi) \
- -ljsoncpp -llog
這裡則指定使用的庫libjsoncpp和liblog
4、java端的介面,注意載入庫的先後順序:
[java] view plaincopy
- System.loadLibrary("jsoncpp");
- System.loadLibrary("main");
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := jsoncpp
LOCAL_CPPFLAGS := -DJSON_IS_AMALGAMATION -fexceptions
LOCAL_SRC_FILES := $(LOCAL_PATH)/jsoncpp/jsoncpp.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/jsoncpp/json
# it is used for ndk-r5
# if you build with ndk-r4, comment it
# because the new Windows toolchain doesn‘t support Cygwin‘s drive
# mapping (i.e /cygdrive/c/ instead of C:/)
#LOCAL_LDLIBS := -L$(call host-path, $(LOCAL_PATH)/../libs/armeabi)
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS) LOCAL_MODULE := system
# for jsoncpp LOCAL_CPPFLAGS := -DJSON_IS_AMALGAMATION
LOCAL_SRC_FILES := system.cpp LOCAL_C_INCLUDES := $(LOCAL_PATH)/jsoncpp
# it is used for ndk-r5
# if you build with ndk-r4, comment it
# because the new Windows toolchain doesn‘t support Cygwin‘s drive
# mapping (i.e /cygdrive/c/ instead of C:/)
LOCAL_LDLIBS := -L$(call host-path, $(LOCAL_PATH)/../libs/armeabi) \ -ljsoncpp -llog
include $(BUILD_SHARED_LIBRARY)