简介:
涉及到一些算法或者底层驱动的时候,往往需要使用jni来开发。现在官方推荐使用CMake工具来开发jni。
使用CMake开发Jni其实挺简单的,要求不高的话只需要简单配置一下就可以使用了。
配置环境
使用CMake进行Jni开发需要使用CMake插件、LLDB插件、NDK插件,这些都可以通过Android Studio很快地安装。
打开SDK Manager,找到Android SDK->SDK Tool选项,安装CMake、LLDB、NDK插件。
创建支持C++代码的工程
默认一路Next,Finish完成创建项目
看下app build.gradle下配置
cpp下CMakeLists.txt是个非常重要的配置文件,看看里面的配置
再看看native-lib.cpp里的代码,这里是JAVA调用C的关键方法具体实现,对Java代码中的声明的native方法在这里用C/C++具体实现功能算法。
在MainActivity中实现了native-lib库的加载和方法的调用
So easy!就这样完成了JNI的基础开发!
在具体实现中如何从Java native方法声明,转化为C实现,方法如下:
1、创建Java类Demo.java
public class Demo { public native int addTwo(int a, int b); public native int addMore(int[] nums, int target); }
2、打开windows的cmd命令(当然也可以使用Android Studio自带的Terminal控制台),切换到Demo.java这个native 方法接口类的路径。然后使用javac Demo.java
将该类转换为.class文件。注意:Demo.java中不要包含中文注釋。
3、接着切换回工程的java目录下,使用javah -classpath . -jni + 包名 + 文件名
生成.h文件(命令中-jni前面的点是必要的)。windows切换上级目录使用cd…命令。
4、执行完成后,可以在java目录下看到一个以包名+文件名的.h文件,里面即写好了Demo.java对应的jni函数名称代码。
/* DO NOT EDIT THIS FILE - it is machine generated */ #include/* Header for class com_wasu_myjni_jni_Demo */ #ifndef _Included_com_wasu_myjni_jni_Demo #define _Included_com_wasu_myjni_jni_Demo #ifdef __cplusplus extern "C" { #endif /* * Class: com_wasu_myjni_jni_Demo * Method: sum * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_wasu_myjni_jni_Demo_addTwo (JNIEnv *, jobject, jint, jint); /* * Class: com_wasu_myjni_jni_Demo * Method: twoSum * Signature: ([II)I */ JNIEXPORT jint JNICALL Java_com_wasu_myjni_jni_Demo_addMore (JNIEnv *, jobject, jintArray, jint); #ifdef __cplusplus } #endif #endif
可以看到,文件里面已经写好Demo.java里面方法相对应的jni函数名了
这时把生成的.h文件里面的内容复制粘贴到我们之前创建的native-lib.cpp文件里面,jni代码里面的命名部分就完成了。然后在native-lib.cpp里具体实现对应的方法即可。
注意:现在Android Sudio提供了快捷方式实现,在Demo.java类中点击显示红色的方法会弹出一项create JNI function for addTwo,点击即可在native-lib.cpp中创建对应的C++方法,实现具体功能即可。
当写好jni函数名后,你会发现Demo.java里面的代码也不再是红色了,说明Demo.java里面的方法能正确调用jni的函数了。在MainActivity中加载native-lib,在具体地方调用Demo中的方法。
// Used to load the 'native-lib' library on application startup. static { System.loadLibrary("native-lib"); }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Example of a call to a native method TextView tv = findViewById(R.id.sample_text); tv.setText(" a + b = " + new Demo().addTwo(2, 3)); //调用处 }