使用JsonCpp在android NDK中解析Json

前端之家收集整理的这篇文章主要介绍了使用JsonCpp在android NDK中解析Json前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

使用JsonCpp在android NDK中解析Json

如果在android SDK环境下,则自带了org.json库,不需要再自行编译。如果在NDK环境下,本人没有找到系统自带的(压根没去找。。),故而决定使用json cpp。在将json cpp集成进去时,发觉网上没有相关的文章,就顺手写写,希望能帮到有需要的人。

JsonCpp是一个开源的Cpp用的json库,下载地址:

http://sourceforge.net/projects/jsoncpp/files/jsoncpp/0.6.0-rc2/

注意下载jsoncpp-src-0.6.0-rc2-amalgamation.tar.gz,这个版本将.h和.cpp合并在一起,而且不需要再configure。(它的make系统我觉得很奇怪。。)

下载完毕后解压缩,放到$project/jni下($project是项目根目录,下同)。

为了避免以后重复编译JsonCpp,所以决定把它编成动态库,独立出来。顺便建立一个测试程序main,放在test下边。路径具体如下:

tree $project/jni/

////////////////////////////////

Android.mk

Application.mk

jsoncpp

-------Android.mkjsonjsoncpp.cpp

test

-------Android.mk main.cpp

(mac没有tree命令,将就下)

1、JsonCpp用到了stl的exception,所以如果你在android的编译系统的Application文件中指定STL库路径时,如果使用:APP_STL := stlport_static,那么就无法通过编译。需要改成:APP_STL := gnustl_static

jni/Application.mk

@H_502_58@
  • #itisneededforndk-r5
  • #APP_STL:=stlport_static
  • APP_STL:=gnustl_static
  • APP_MODULES:=jsoncppmain

  • 2、项目的Android.mk,指定了要编译的两个子Android.mk
    jni/Android.mk
    @H_502_58@
  • LOCAL_PATH:=$(callmy-dir)
  • include$(CLEAR_VARS)
  • subdirs:=$(LOCAL_PATH)/test/Android.mk
  • subdirs+=$(LOCAL_PATH)/jsoncpp/Android.mk
  • include$(subdirs)

  • 3、jsoncpp的make file。注意LOCAL_CPPFLAGS := -DJSON_IS_AMALGAMATION -fexceptions 这一行。宏定义JSON_IS_AMALGAMATION告诉jsoncpp是amalgamation版本,即是我们刚才下载的版本。-fexceptions则开启exception应用。

    jni/jsoncpp/Android.mk

    @H_502_58@
  • LOCAL_PATH:=$(callmy-dir)
  • include$(CLEAR_VARS)
  • LOCAL_MODULE:=jsoncpp
  • LOCAL_CPPFLAGS:=-DJSON_IS_AMALGAMATION-fexceptions
  • LOCAL_SRC_FILES:=jsoncpp.cpp
  • LOCAL_C_INCLUDES:=$(LOCAL_PATH)/json
  • #itisusedforndk-r5
  • #ifyoubuildwithndk-r4,commentit
  • #becausethenewWindowstoolchaindoesn'tsupportCygwin'sdrive
  • #mapping(i.e/cygdrive/c/insteadofC:/)
  • LOCAL_LDLIBS:=-L$(callhost-path,$(LOCAL_PATH)/../../libs/armeabi)
  • include$(BUILD_SHARED_LIBRARY)

  • 4、我们的测试程序的make file。注意LOCAL_C_INCLUDES := $(LOCAL_PATH)/../jsoncpp这一行,我们指定了头文件的地址为,当前路径(即$project/jni/test/)的上一级的jsoncpp文件夹,即$project/jni/jsoncpp/,这样在使用中我们需要inlcude的就是 "json/json.h"。
    @H_502_58@
  • LOCAL_LDLIBS:=-L$(callhost-path,$(LOCAL_PATH)/../../libs/armeabi)\
  • -ljsoncpp-llog
  • 这里则指定使用的库libjsoncpp和liblog

    jni/test/Android.mk

    @H_502_58@
  • LOCAL_PATH:=$(callmy-dir)
  • include$(CLEAR_VARS)
  • LOCAL_MODULE:=main
  • #forjsoncpp
  • LOCAL_CPPFLAGS:=-DJSON_IS_AMALGAMATION
  • LOCAL_SRC_FILES:=main.cpp
  • LOCAL_C_INCLUDES:=$(LOCAL_PATH)/../jsoncpp
  • #itisusedforndk-r5
  • #ifyoubuildwithndk-r4,$(LOCAL_PATH)/../../libs/armeabi)\
  • -ljsoncpp-llog
  • include$(BUILD_SHARED_LIBRARY)

  • 5、测试程序文件main.cpp。因为是cpp,所以与java函数的接口就加extern "C",要不编译后会找不到函数名。jsoncpp 的使用很简单,就是定义一个Json::Value,然后把数据填进去就行了,它会根据数据类型重载的。

    jni/test/main.cpp

    @H_502_58@
  • #include<jni.h>
  • #include<android/log.h>
  • #include"json/json.h"
  • #defineLOG_TAG"main"
  • #defineLOGD(...)__android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
  • extern"C"
  • {
  • jstringJava_com_kevin_tutorial_jsoncpp_ToUseJsoncppActivity_toBuildJson(JNIEnv*env,jobjectthiz,jintid,jstringname){
  • jbooleanisCopy=0;
  • constchar*c_name=env->GetStringUTFChars(name,&isCopy);
  • LOGD("oncalling,id:%d,name:%s",id,c_name);
  • //tobuildajsonobjectwithidandname
  • Json::Valueuser;
  • user["id"]=id;
  • user["name"]=c_name;
  • constchar*json_str=user.toStyledString().c_str();
  • jstringresult=env->NewStringUTF(json_str);
  • env->ReleaseStringUTFChars(name,c_name);
  • returnresult;
  • }/*Java_com_kevin_tutorial_jsoncpp_ToUseJsoncppActivity_toBuildJson*/
  • }/*extern"C"*/

  • 6、java端的接口,注意加载库的先后顺序:
    1. System.loadLibrary("jsoncpp");
    2. System.loadLibrary("main");

    $project/src/com/kevin/tutorial/jsoncpp/ToUseJsoncppActivity.java

    1. packagecom.kevin.tutorial.jsoncpp;
    2. importandroid.app.Activity;
    3. importandroid.os.Bundle;
    4. importandroid.util.Log;
    5. importandroid.view.View;
    6. importandroid.view.View.OnClickListener;
    7. importandroid.widget.Button;
    8. publicclassToUseJsoncppActivityextendsActivity{
    9. privatestaticfinalStringTAG="ToUseJsoncppActivity.java";
    10. @Override
    11. publicvoidonCreate(BundlesavedInstanceState){
    12. super.onCreate(savedInstanceState);
    13. setContentView(R.layout.main);
    14. ButtonbtnOk=(Button)findViewById(R.id.btnOk);
    15. btnOk.setOnClickListener(newOnClickListener(){
    16. @Override
    17. publicvoidonClick(Viewv){
    18. //TODOAuto-generatedmethodstub
    19. intid=1001;
    20. Stringname="Kevin";
    21. Stringresult=toBuildJson(id,name);
    22. Log.i(TAG,String.format("Id:%1$d,Name:%2$s,Thejsonformatedstring:%3$s",name,result));
    23. }
    24. });
    25. }
    26. privatestaticnativeStringtoBuildJson(intid,Stringname);
    27. static{
    28. System.loadLibrary("jsoncpp");
    29. System.loadLibrary("main");
    30. }
    31. }


    7、最后在项目路径下,ndk-build编译(需配置ndk的环境变量)。注意如果以前有使用过APP_STL := stlport_static,那么在build之前需要ndk-build clean一下。

    然后android update project -p ./ 建立ant,再ant debug install,安装到机器上。


    mac v10.6.8,android 2.3.3,android-ndk-r6b下测试通过,完整项目见附件:

    。。。不知道怎么上传附件

    猜你在找的Json相关文章