Android NDK安卓-JNI

JNI学习记录1-初建JNI工程

2017-02-16  本文已影响182人  ai___believe

JNI学习记录1-初建JNI工程
JNI学习记录2-local refence崩溃问题
JNI学习记录3-String and Array
JNI学习记录4-Fields
JNI学习记录5-Methods

在开发过程中遇到一些JNI问题,系统学习下.

一、java调用c++##

失败经历####

下面这篇教程较好,所以先按照他所述,一步一步进行。

http://www.open-open.com/lib/view/open1359700820369.html

环境:eclipse+vs2013+ndk

概括步骤为下:
****编写好java文件 ->javac test.java ->javah -jni 类 ->得到jni头文件 ->编写c/c++文件实现****
****1 、编写好java文件 ****
****JNI_javaCallc_test.java****

package test;
public class JNI_javaCallc_test {
public native int intMethod(int n);
public native boolean booleanMethod(boolean bool);
public native String stringMethod(String text);
public native int intArrayMethod(int[] intArray);
//java main方法
public static void main(String[] args){
//包含c语言动态库
System.loadLibrary("test_JNI_javaCallc_test"); //test_
JNI_javaCallc_test sample = new JNI_javaCallc_test();
int square = sample.intMethod(5);
boolean bool = sample.booleanMethod(true);
String text =sample.stringMethod("JAVA");
int sum = sample.intArrayMethod(new int[] { 1, 1, 2, 3, 5, 8, 13 });
System.out.println("intMethod: " + square);
System.out.println("booleanMethod: " + bool);
System.out.println("stringMethod: " + text);
System.out.println("intArrayMethod: " + sum);
}
} `

****2、生成JNI_javaCallc_test2进制文件****
javac JNI_javaCallc_test.java

****3、生成test_JNI_javaCallc_test.h****
javah -classpath . test.JNI_javaCallc_test

****4、编写test_JNI_javaCallc_test.c****

include <jni.h>
/* Header for class test_JNI_javaCallc_test */
JNIEXPORT jint JNICALL Java_test_JNI_1javaCallc_1test_intMethod(JNIEnv *env, jobject obj, jint num)
{
return num * num;
}
JNIEXPORT jboolean JNICALL Java_test_JNI_1javaCallc_1test_booleanMethod
(JNIEnv *env, jobject obj, jboolean boolean) {
return!boolean;
}
JNIEXPORT jstring JNICALL Java_test_JNI_1javaCallc_1test_stringMethod
(JNIEnv\ env, jobject obj, jstring string)
{
const char *str = (
env)->GetStringUTFChars(env, string, 0);
char cap[128];
strcpy(cap, str);
(env)->ReleaseStringUTFChars(env, string, str);
return (
env)->NewStringUTF(env, strupr(cap));
}
JNIEXPORT jint JNICALL Java_test_JNI_1javaCallc_1test_intArrayMethod
(JNIEnv *env, jobject obj, jintArray array)
{
int i, sum = 0;
jsize len = (*env)->GetArrayLength(env, array);
jint*body = (*env)->GetIntArrayElements(env, array, 0);
for(i=0; i<len; i++)
{ sum += body[i];
}
(*env)->ReleaseIntArrayElements(env, array, body, 0);
return sum;
}

****5、生成test_JNI_javaCallc_test.dll****
cl -I"D:\Java\jdk1.8.0_112\include" -I"D:\Java\jdk1.8.0_112\include\win32" -I"D:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include" -LD test_JNI_javaCallc_test.c -Fe test_JNI_javaCallc_test
****6、运行****
java -cp . test.JNI_javaCallc_test (这里为class文件)

****然而,最后一步总会出错,可能是NDK和VS不匹配的原因吧,具体不详。总之,这个方法没有成功,但是学到了怎么从java类文件到jni的.h文件,再到.c/.cpp文件。****

成功经历1##

环境:android stdio 2.2.2

Z(Y)MDZOFDY9PC_Z21J}$9G.png

选上这一项直接支持c++,这种方法使用的是cmake。

成功经历2##

下面使用ndk_build,还是使用android stdio 2.2.2
以此博文为例:

http://blog.csdn.net/yanbober/article/details/45309049/

1、创建工程时,不勾选支持c++,按照上文所述方法,一直进行下来,在build时会报错。
2、此时需要在jni文件夹下添加,Android.mk文件。

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := YanboberJniLibName
LOCAL_LDFLAGS := -Wl,--build-id
LOCAL_LDLIBS :=
-llog
-lz
-lm
LOCAL_SRC_FILES :=
C:\Users\zhanganl\Desktop\Jni_test\jni_test_stdio\jni_test_stdio\app\src\main\jni\jnitest.cpp
LOCAL_C_INCLUDES += C:\Users\zhanganl\Desktop\Jni_test\jni_test_stdio\jni_test_stdio\app\src\main\jni
LOCAL_C_INCLUDES += C:\Users\zhanganl\Desktop\Jni_test\jni_test_stdio\jni_test_stdio\app\src\debug\jni
include $(BUILD_SHARED_LIBRARY)

3、在app的build.gradle的android括号最后添加
>externalNativeBuild {
ndkBuild{
path "src/main/jni/Android.mk"
}
指向Android.mk。图形如下:

jni_build_gradle.png

***此步骤可以完成java调用c/c++的功能 ***

完整工程

https://github.com/zhanganl/jni_test/tree/master

疑惑:

https://github.com/wobiancao/NdkJniDemo
这个demo没有编写Android.mk,不知道为什么可以自动生成Android.mk。

推荐文档:
http://docs.anysdk.com/others/information/jni-tutorial/

上一篇下一篇

猜你喜欢

热点阅读