本文实现在Android app中使用调用jni库调用本地C/C++方法。
1.新建android工程
2.新建java上层方法
本例子在工程中新建 cn.landsem.jnistudy 包,在其中新建TestManager类用于调用本地C/C++方法,该类的代码如下:
1. package cn.landsem.jnistudy;
2.
3. import android.util.Log;
4.
5. public class TestManager {
6. public static String TAG = "TestManager";
7. static {
8. try {
9. "lstest");
10. catch (Exception e) {
11. e.printStackTrace();
12. Log.d(TAG,e.getMessage());
13. }
14. "native_init");
15. nativeInit();
16. }
17.
18. public int add(int i,int j) {
19. "add");
20. return nativeAdd(i,j);
21. }
22.
23. private static native void nativeInit();
24. private static native int nativeAdd(int i,int j);
25. }
3.创建jni头文件
打开dos命令窗口,切换到工程目录下的“bin\classes”目录,输入javah -jni cn.landsem.jnistudy.TestManager命令,命令执行成功后会在该目录下生成对应的jni头文件,如本文中完成上述命令会生成 cn_landsem_jnistudy_TestManager.h 文件,文件内容如下:
1. /* DO NOT EDIT THIS FILE - it is machine generated */
2. #include <jni.h>
3. /* Header for class cn_landsem_jnistudy_TestManager */
4.
5. #ifndef _Included_cn_landsem_jnistudy_TestManager
6. #define _Included_cn_landsem_jnistudy_TestManager
7. #ifdef __cplusplus
8. extern "C" {
9. #endif
10. /*
11. * Class: cn_landsem_jnistudy_TestManager
12. * Method: nativeInit
13. * Signature: ()V
14. */
15. JNIEXPORT void JNICALL Java_cn_landsem_jnistudy_TestManager_nativeInit(JNIEnv *, jclass);
16.
17. /*
18. * Class: cn_landsem_jnistudy_TestManager
19. * Method: nativeAdd
20. * Signature: (II)I
21. */
22. JNIEXPORT jint JNICALL Java_cn_landsem_jnistudy_TestManager_nativeAdd(JNIEnv *, jclass, jint, jint);
23.
24. #ifdef __cplusplus
25. }
26. #endif
27. #endif
4.新建jni实现
在工程中新建jni目录,将上部操作中生成的jni头文件拷贝到该目录,新建一个c++源文件实现jni中定义的方法,如本文在jni目录下新建cn_landsem_jnistudy_TestManager.cpp文件用于实现上述方法,该方法实现代码如下:
1. #include "android_runtime/AndroidRuntime.h"
2. #include "JNIHelp.h"
3. #include "jni.h"
4. #include "utils/Log.h"
5. #include "utils/misc.h"
6. #include "cn_landsem_jnistudy_TestManager.h"
7. #include <android/log.h>
8. #include <stdio.h>
9. #include <string.h>
10. #include <stdlib.h>
11. #include <errno.h>
12. #include <unistd.h>
13. #include <sys/types.h>
14.
15. #define LOG_TAG "Test_JNI"
16.
17. JNIEXPORT void JNICALL Java_cn_landsem_jnistudy_TestManager_nativeInit
18. (JNIEnv *, jclass) {
19. "call Java_cn_landsem_jnistudy_TestManager_nativeInit");
20. }
21.
22. /*
23. * Class: cn_landsem_jnistudy_TestManager
24. * Method: native_add
25. * Signature: (II)I
26. */
27. JNIEXPORT jint JNICALL Java_cn_landsem_jnistudy_TestManager_nativeAdd
28. (JNIEnv *, jclass, jint, jint) {
29. "call Java_cn_landsem_jnistudy_TestManager_nativeAdd");
30. return 0;
31. }
5、生成jni so库
在jni目录下新建Android.mk文件用于编译生成jni库,该文件内容如下:
1. # Copyright (C) 2010 The Android Open Source Project
2. #
3. # Licensed under the Apache License, Version 2.0 (the "License");
4. # you may not use this file except in compliance with the License.
5. # You may obtain a copy of the License at
6. #
7. # http://www.apache.org/licenses/LICENSE-2.0
8. #
9. # Unless required by applicable law or agreed to in writing, software
10. # distributed under the License is distributed on an "AS IS" BASIS,
11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12. # See the License for the specific language governing permissions and
13. # limitations under the License.
14.
15. LOCAL_PATH:= $(call my-dir)
16.
17. include $(CLEAR_VARS)
18. LOCAL_SRC_FILES := cn_landsem_jnistudy_TestManager.cpp
19.
20. LOCAL_SHARED_LIBRARIES := \
21. libcutils \
22. libutils \
23. liblog \
24.
25. LOCAL_MODULE:= liblstest
26.
27. include $(BUILD_SHARED_LIBRARY)
6、包含jni库到工程中
在工程libs目录下新建armeabi目录和armeabi-v7a目录,将生成的jni库放到该目录下。
7、调用
在工程中调用 TestManager 类即可测试。
8、源码下载
工程导入后会出错
具体错误在budild.gradle中、
修改 android 下
compileSdkVersion 19
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}