第一步:配置ndk-build的环境变量,方便后面生成动态库时在dos窗口下直接使用,就不用每次都要进入到ndk-build所在的目录下;
第二步:在mainactivity中定义本地方法,这个方法就相当于c程序中的方法,也可以在Java包下单独定义这个本地方法。如下所示:
public native int hello();
第三步:在工程目录下新建jni目录,并在jni目录下新建.c文件,这里创建helloworld.c文件;
第四步:在jni文件夹下新建Android.mk文件,写入如下内容:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := helloworld.c
include $(BUILD_SHARED_LIBRARY)
其中LOCAL_PATH :=$(call my-dir)表示加载本地的jni目录,当在dos窗口中进行ndk-build命令时,会找到工程目录下的jni目录;
include $(CLEAR_VARS)表示下次重新生成动态库时,清理掉上次生成的变量;
LOCAL_MODULE := hello表示指定生成动态库的名称;
LOCAL_SRC_FILES :=helloworld.c表示指定了本地c文件,即在jni目录下的.c文件的名称;
include $(BUILD_SHARED_LIBRARY)表示指定生成库的类型为动态库,即.so,如果是BUILD_STATIC_LIBRARY表示静态库.a。
第五步:使用javah生成头文件
1、在dos窗口中将路径切换到工程的src目录下,使用javah命令生成头文件,并刷新工程
如下所示:E:\Users\SunXing\workspace\JNIDemo>cd /d E:\Users\SunXing\workspace\JNIDemo\src
E:\Users\SunXing\workspace\JNIDemo\src>javah com.example.jnidemo.MainActivity
生成的头文件内容为:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_jnidemo_MainActivity */
#ifndef _Included_com_example_jnidemo_MainActivity
#define _Included_com_example_jnidemo_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_jnidemo_MainActivity
* Method: hello
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_example_jnidemo_MainActivity_hello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
2、将工程生成的头文件拖到jni目录下
3、将头文件中的方法拷贝到.c文件中,实现方法体,并将jni导入到.c文件中,这样.c文件中的内容变为
#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
JNIEXPORT jint JNICALL Java_com_example_jnidemo_MainActivity_hello
(JNIEnv * env, jobject obj){
return 5;
}
第六步:在dos窗口下使用ndk-build命令生成动态库,运行正确的结果如下所示:
E:\Users\SunXing\workspace\JNIDemo\src>ndk-build
Android NDK: Found platform level in E:/Users/SunXing/workspace/JN
properties. Setting APP_PLATFORM to android-19.
Android NDK: WARNING: APP_PLATFORM android-19 is higher than andro
on 14 in E:/Users/SunXing/workspace/JNIDemo/AndroidManifest.xml. N
ll *not* be comptible with devices older than android-19. See http
oglesource.com/platform/ndk/+/master/docs/user/common_problems.md
mation.
[arm64-v8a] Compile : hello <= helloworld.c
[arm64-v8a] SharedLibrary : libhello.so
[arm64-v8a] Install : libhello.so => libs/arm64-v8a/libhell
[armeabi-v7a] Compile thumb : hello <= helloworld.c
[armeabi-v7a] SharedLibrary : libhello.so
[armeabi-v7a] Install : libhello.so => libs/armeabi-v7a/lib
[x86] Compile : hello <= helloworld.c
[x86] SharedLibrary : libhello.so
[x86] Install : libhello.so => libs/x86/libhello.so
[x86_64] Compile : hello <= helloworld.c
[x86_64] SharedLibrary : libhello.so
[x86_64] Install : libhello.so => libs/x86_64/libhello.so
第七步:在Java文件(MainActivity)中加载上述生成的动态库,并调用上述自定义的本地方法,完整的MainActivity代码如下所示:
public class MainActivity extends Activity {
private Button callMethod;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
callMethod = (Button) findViewById(R.id.btu_call_method_from_c);
callMethod.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//1,加载动态库
System.loadLibrary("hello");
//2,调用本地方法
int result = hello();
System.out.println("==========result==========="+result);
}
});
}
public native int hello();
}
运行程序,这样就完成了一个简单的jni调用本读程序。