NDK Demo 程序

简单的 NDK Demo 程序

       好了,环境已搭建好, 现在我们开始建立一个简单的 ndk 程序来体验下整个 ndk 开发流程 :

第一步:首先我们在eclipse 中新建一个工程,工程名这里是NdkPassNormalData 。   在工程   中新建一个java 类:CallNativeDemo.java

内容如下:

package com.jiubang.Demo.Ndk.PassNormalData;

public class CallNativeDemo {

 static {

       System.loadLibrary ( "NdkPassDataDemo" );

// 注意库文件名,对于 NdkPassDataDemo 系统会在该类初始化时加载 //libNdkPassDataDemo.so 库 , 切记勿画蛇添足加上前面的 lib 与 .so 扩展名

    }

    public native int Sum( int a , int b); // 加上 native 表示该方法由 .so 实现

    public native String StrCat(String str1 , String str2);

}

编写好该 java 文件后,先编译,然后用 javah 生成 ndk 中我们需要的 c 头文件 :

进入到工程的 bin 目录下输入:

javah  -jni com.jiubang.Demo.Ndk.PassNormalData.CallNativeDemo

然后会在当前目录下生成com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo.h 文件

内容大概如下:

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo */

#ifndef _Included_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo

#define _Included_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo

#ifdef __cplusplus

extern "C" {

#endif

/*

  * Class:     com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo

  * Method:    Sum

  * Signature: (II)I

  */

JNIEXPORT jint JNICALL Java_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo_Sum

  (JNIEnv *, jobject, jint, jint);

/*

  * Class:     com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo

  * Method:    StrCat

  * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

  */

JNIEXPORT jstring JNICALL Java_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo_StrCat

  (JNIEnv *, jobject, jstring, jstring);

#ifdef __cplusplus

}

#endif

#endif

第二步:在我们新的工程中加一个名为:jni 的文件夹。这个文件夹就是放原生态c/c++ 的源码的地方,我们make 的时候cygwin 就是编译这个文件夹的。

第三步:在jni 文件夹里新建一个Android.mk 文件。注意,后缀为.mk , 且文件夹一定要小写

Android.mk 的内容为: 

LOCAL_PATH := $(call my-dir) <--------- 返回当前路径,默认的,不需要更改

include $(CLEAR_VARS)      <-------- 清除先前定义的环境变量,默认的,不需要更改

LOCAL_MODULE := NdkPassDataDemo <-------- 在 java 类引用时的名称

LOCAL_CPP_EXTENSION := cpp

LOCAL_SRC_FILES := Fun.cpp <------ 需要编译的源文件

LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib –llog <-- 打 log 要用到的库,这里暂时不大明白为什么库名是这样 …

include $(BUILD_SHARED_LIBRARY) <-- 这里指的是动态库,默认的,不需要更改

第四步:在jni 文件夹里新建一个 Fun.cpp 的文件。这个文件就是c/c++ 文件。

             Fun.cpp 的内容为:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <android/log.h>

#include "com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo.h"

// 对应 public native int Sum( int a , int b) 的实现

jint JNICALL Java_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo_Sum(JNIEnv* aEnv, jobject aThis, jint aParamA, jint aParamB)

{

    int sum = 0;

    __android_log_print(ANDROID_LOG_INFO , "Ndk_PassNormalData" , "CallNativeDemo_Sum Coming");

    sum = aParamA + aParamB;

    FILE* file = fopen("/sdcard/hello.txt","w+");

    if (file != NULL)

    {

       fputs("HELLO WORLD!/n", file);

       fflush(file);

       fclose(file);

    }

    __android_log_print(ANDROID_LOG_INFO , "Ndk_PassNormalData" , "CallNativeDemo_Sum Leaving");

    return sum;

}

// 对应 public native String StrCat(String str1 , String str2) 实现

jstring JNICALL Java_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo_StrCat(JNIEnv *aEnv, jobject aThis, jstring aStr1, jstring aStr2)

{

    __android_log_print(ANDROID_LOG_INFO , "Ndk_PassNormalData" , "CallNativeDemo_StrCat Coming");

    const char* str1 = aEnv->GetStringUTFChars(aStr1 , 0);

    const char* str2 = aEnv->GetStringUTFChars(aStr2 , 0);

    //char* str1 = (char*)(*aEnv)->GetStringUTFChars(aEnv ,aStr1 , 0);

    //char* str2 = (char*)(*aEnv)->GetStringUTFChars(aEnv ,aStr2 , 0);

    int str1_len = strlen(str1);

    int str2_len = strlen(str2);

    // char* pszRet = malloc(str1_len + str2_len + 1);

    char* pszRet = new char[str1_len + str2_len + 1];

    strcpy(pszRet, str1);

    strcat(pszRet, str2);

    //jstring jstrRet = (*aEnv)->NewStringUTF(aEnv, pszRet);

    jstring jstrRet = aEnv->NewStringUTF(pszRet);

    // free(pszRet);

    delete pszRet;

    __android_log_print(ANDROID_LOG_INFO , "Ndk_PassNormalData" , "CallNativeDemo_StrCat Leaving");

    return jstrRet;

}

然后就可以开始编译了 :

打开 cygwin, 进入到工程的 jni 目录,然后执行 ndk-build

有看到 Install 就 OK 了

然后会发现工程目录下会多了一个 lib 与 obj 的目录

最后在 android 工程里加上调用这些 ndk 本地方法的代码:

CallNativeDemo nativeDemo = new CallNativeDemo();  

int value = nativeDemo.Sum(10, 20);  

String str = nativeDemo.StrCat("who", "are you");  

TextView v = (TextView)findViewById(R.id.textview1);  

v.setText(str);   

posted @ 2012-03-20 12:28  木子你妹  阅读(1692)  评论(0编辑  收藏  举报