实现功能: JAVA 调用 C/C++ 底层代码
须知: 只有程序成为处理器杀手的时候,以及保证安全的时候才用 NDK
环境: cygwin+android sdk+android ndk eclipse cdt eclipse sdt
例子:详细请查看“历上最强的 NDK 入门与实践资料”文档
实现细节:
Jni.java
package com.yarin.android.HelloNDK;
public class Jni
{
/* 声明本地方法 */
// 得到一个 int 型数据
public native int getCInt ();
// 得到一个字符串数据
public native String getCString ();
}
在 HelloNDK .java 中
package com.yarin.android.HelloNDK;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloNDK extends Activity
{
// 装载动态库“ libHello.so ”
static
{
System.loadLibrary("HelloNDK");
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Jni jni = new Jni();
TextView textView = new TextView(this);
// 调用原生方法
textView.setText(jni.getCString()+Integer.toString(jni.getCInt()));
setContentView(textView);
}
}
生成 JNI 头文件
下面生成 JNI 头文件啦,使用 javah 命令,对 JNI..java 这个文件生成,别搞错啦!
使用 cmd 进入 android 项目的 bin 目录中,然后执行 javah -classpath . -jni cc.androidos.jni.JNI 这个命令。别忘记包名!( ^_^ )
如下所示:
产生如下文件:
将其拷贝到 jni ,代码清单如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_yarin_android_HelloNDK_Jni */
#ifndef _Included_com_yarin_android_HelloNDK_Jni
#define _Included_com_yarin_android_HelloNDK_Jni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_yarin_android_HelloNDK_Jni
* Method: getCInt
* Signature: ()Ljava /lang /String;
*/
JNIEXPORT jint JNICALL Java_com_yarin_android_HelloNDK_Jni_getCInt
(JNIEnv *env, jobject thiz);
/*
* Class: com_yarin_android_HelloNDK_Jni
* Method: getCString
* Signature: ()Ljava /lang /String;
*/
JNIEXPORT jstring JNICALL Java_com_yarin_android_HelloNDK_Jni_getCString
(JNIEnv *env, jobject thiz);
#ifdef __cplusplus
}
#endif
#endif
// 防止再次被编译,提高效率
在同源文件夹 jni, 在该目录建立两个文件 android.mk 和 com_yarin_android_HelloNDK_Jni.c
Android.mk 清单如下:
LOCAL_PATH : = $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE : = HelloNDK
LOCAL_SRC_FILES : = com_yarin_android_HelloNDK_Jni.c
include $(BUILD_SHARED_LIBRARY)
com_yarin_android_HelloNDK_Jni.c 的清单如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "com_yarin_android_HelloNDK_Jni.h"
int add2 ()
{
int x,y;
x = 1000;
y = 8989;
x+=y;
return x;
}
JNIEXPORT jint JNICALL Java_com_yarin_android_HelloNDK_Jni_getCInt
(JNIEnv *env, jobject thiz)
{
return add2 ();
}
JNIEXPORT jstring JNICALL Java_com_yarin_android_HelloNDK_Jni_getCString
(JNIEnv *env, jobject thiz)
{
return (*env)->NewStringUTF(env, "HelloNDK---->>" );
}
运行 1. cygwin
2. cd $ANDROID_NDK_ROOT
3. ./ndk -build -C samples/myjni
就会在当前目录下生成
这样就产生了 linux 下面的动态链接库( win32 下面为 dll 后缀名)
整个项目的目录如下:
图表 1
运行实例:截图如下:
附录:
其实很好理解的,仅仅是换个了别名而以,定义如下
typedef uint8_t jboolean; /* unsigned 8 bits */
typedef int8_t jbyte; /* signed 8 bits */
typedef uint16_t jchar; /* unsigned 16 bits */
typedef int16_t jshort; /* signed 16 bits */
typedef int32_t jint; /* signed 32 bits */
typedef int64_t jlong; /* signed 64 bits */
typedef float jfloat; /* 32-bit IEEE 754 */
typedef double jdouble; /* 64-bit IEEE 754 */
#else
typedef unsigned char jboolean; /* unsigned 8 bits */
typedef signed char jbyte; /* signed 8 bits */
typedef unsigned short jchar; /* unsigned 16 bits */
typedef short jshort; /* signed 16 bits */
typedef int jint; /* signed 32 bits */
typedef long long jlong; /* signed 64 bits */
typedef float jfloat; /* 32-bit IEEE 754 */
typedef double jdouble; /* 64-bit IEEE 754 */
#endif
typedef jint jsize;
还有一些调用平时注意的声明
#define JNI_FALSE 0
#define JNI_TRUE 1
#define JNI_VERSION_1_1 0x00010001
#define JNI_VERSION_1_2 0x00010002
#define JNI_VERSION_1_4 0x00010004
#define JNI_VERSION_1_6 0x00010006
#define JNI_OK (0) /* no error */
#define JNI_ERR (-1) /* generic error */
#define JNI_EDETACHED (-2) /* thread detached from the VM */
#define JNI_EVERSION (-3) /* JNI version error */
#define JNI_COMMIT 1 /* copy content, do not free buffer */
#define JNI_ABORT 2 /* free buffer w/o copying back */
#define JNIIMPORT
#define JNIEXPORT
#define JNICALL