您的位置:首页 > 移动开发 > Android开发

android NDK/JNI demo

2016-10-19 11:21 309 查看
NDK配置请查看我的另外一篇博客。再次不阐述。

1.在eclipse里面编写一个java文件:TestJNI.java

<span style="font-size:14px;">package com.example.jnidemo;

/**
* JNI demo
*
* @author **
* @version [ 2016-10-19]
* @see
* @since
*/
public class TestJNI
{
static public native String AddStr(String strA, String strB);

static public native int AddInt(int a, int b);
}</span>

2.生成 .h 的c++头文件

(1)用cmd命令定位到TestJNI.java 所在目录,输入“javac

TestJNI.java“后回车,生成TestJNI.class文件(如果是用的Eclipse建的工程,在JNIDemo\bin\classes\com\example\jnidemo目录下就已经有TestJNI.class文件了)。

备注:如果是用命令行生成class文件,需要将里面的中文去掉,否则会报GBK错误。

(2)将TestJNI.class拷贝到JNIDemo\bin\classes\com\example\jnidemo目录,将cmd命令定位到

JNIDemo\bin\classes目录(注:最好在classex文件夹下,不要在TestJNI目录下,否则因为包名可能会引起编译出错),输入”javah -classpath . -jni com.example.jnidemo.TestJNI“后回车,在

JNIDemo\bin\classes目录下就生成了C++头文件com_example_jnidemo_TestJNI.h

com_example_jnidemo_TestJNI.h文件如下:

<span style="font-size:14px;">/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_jnidemo_TestJNI */

#ifndef _Included_com_example_jnidemo_TestJNI
#define _Included_com_example_jnidemo_TestJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_jnidemo_TestJNI
* Method: AddStr
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_jnidemo_TestJNI_AddStr
(JNIEnv *, jclass, jstring, jstring);

/*
* Class: com_example_jnidemo_TestJNI
* Method: AddInt
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_example_jnidemo_TestJNI_AddInt
(JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif</span>

3.在jni目录下新建一个Android.mk文件,其内容如下(关于mk文件需要注意,很重要,还有c和c++文件的mk文件还不一样,此处是调用c语言的mk文件,至于其他的怎么调用,自己百度一下)

注:引入下面的代码,记得修改名称,否则不能编译成so文件

<span style="font-size:14px;">LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := TestJNI
LOCAL_SRC_FILES := Copy of com_example_jnidemo_TestJNI.c
include $(BUILD_SHARED_LIBRARY)</span>

4. 将刚刚手动生成的com_example_jnidemo_TestJNI.h拷贝到TestJNI工程的jni目录下,

com_example_jnidemo_TestJNI.c文件完成头文件中函数的实现,其内容如下:

<span style="font-size:14px;">com_example_jnidemo_TestJNI.c

#include "com_example_jnidemo_TestJNI.h"
#include <stdlib.h>
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_jnidemo_TestJNI
* Method: AddStr
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_jnidemo_TestJNI_AddStr
(JNIEnv *env, jclass arg, jstring instringA, jstring instringB){
jstring str = (*env)->NewStringUTF(env, "HelloWorld from JNI !");
return str;
}

/*
* Class: com_example_jnidemo_TestJNI
* Method: AddInt
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_example_jnidemo_TestJNI_AddInt
(JNIEnv *env, jclass arg, jint a, jint b)
{
return a + b;
}

#ifdef __cplusplus
}
#endif</span>

此刻,当编辑com_example_jnidemo_TestJNI.c并保存后,project下的—clean  一下工程,就可以看到TestNkd工程下的obj/local/armeabi目录下将自动生成libTestJNI.so库。

5.在MainActivity.java中完成对TestJNI.java中函数的调用(首先静态加载动态链接so库):

<span style="font-size:14px;">package com.example.jnidemo;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity
{
static
{
System.loadLibrary("TestJNI");
}

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);

// 第一个方法传入的两个参数没有做操作,直接返回hello jni,不用管
String str = TestJNI.AddStr("test", "test");

// 第二个方法暂时不实现
// int iSum = JniClient.AddInt(5, 2);
// String strSum = "5 + 7 = " + iSum;

TextView tv1 = new TextView(this);
tv1.setText(str);
setContentView(tv1);
}
}</span>
9a3d

6.运行TestJNI工程,在控制台中可以看到界面输出来自com_example_jnidemo_TestJNI.c 文件中的“HelloWorld from JNI ! "了。

NDK实例到此完成。

后续更复杂的操作就需要深入的学习NDK/JNI了,

比如C/C++与Java的数据类型转换,以及Android.mk文件的编写格式等。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: