原文地址:
文章主要是转载别人的,但是照着这文章使用的时候遇到了各种坑,一同记录上,方便后来JNI入门的人避免踩坑。
首先,3.0以上的android studio最好使用cmake的方式取打包jni文件,否则会遇到各种解决不了的问题。3.0以后cmake也是google推荐的方式。
一/前提下是要装了NDK
image.png
image.png
image.png
步骤1:
创建一个生成头文件的java文件,作为模板
public class Java2CJNI {
static {
//System的S是大写
System.loadLibrary("Java2C");
}
//这个就是我们将来需要调用的方法
public native String java2C();
}
通过Terminal输入命令生成头文件:
生成对应头文件所在的包名+类名
javah -classpath F:\project7\JNINDKStuddy\app\build\intermediates\classes\debug -jni com.jnindkstuddy.Java2CJNI
image.png
其中JNINDKStuddy是项目的包名。按下enter键后,如果成功,就会生成.h文件。
image.png
下面就是com_jnindkstuddy_Java2CJNI.h的代码
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jnindkstuddy_Java2CJNI */
#ifndef _Included_com_jnindkstuddy_Java2CJNI
#define _Included_com_jnindkstuddy_Java2CJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jnindkstuddy_Java2CJNI
* Method: java2C
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_jnindkstuddy_Java2CJNI_java2C
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
步骤2:
新建一个Java2C.cpp文件(.cpp是c++,.c是C)
把上面com_jnindkstuddy_Java2CJNI.h的函数代码复制到新建的这个Java2C.cpp文件中。代码如下
#include <jni.h>
#include "com_jnindkstuddy_Java2CJNI.h"
JNIEXPORT jstring JNICALL Java_com_jnindkstuddy_Java2CJNI_java2C(JNIEnv* env, jobject instance)
{
return (env)->NewStringUTF("I am From Native C");
}
步骤3:
配置studio文件:
1.配置 CMakeLists.txt,as 3.0后台打so库需要在CMake下。
image.png
CMakeLists.txt如下:
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library. 设置生成so文件名
Java2C
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s). 要编译的C/C++文件
src/main/jni/Java2C.cpp)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library. 指定连接的目标库
Java2C
# Links the target library to the log library
# included in the NDK.
${log-lib} )
image.png
image.png
构建。
image.png
如果没有报错的,就会生成so库。
OK,这里我们就谈报错,我这里就遇到了各种坑。
1。这里有可能会报一个CMake ‘3.6.0’ was not found in PATH or by cmake.dir property. - CMake ‘3.10.2’ found in SDK did not match requested version ‘3.6.0’.的错误。
这个解决方式就是配置3.10.2为要使用的版本。如下图:
2。继续clean,这时候有可能会报错Failed to notify build listener
参考文章:Failed to notify build listener. 的一些处理经历_a260724032的博客-CSDN博客
主要是因为gradle版本的原因。我的解决方式就是指定gradle版本和插件版本:
gradle tool的依赖版本改为3.2.0
gradle-wrapper.properties中的distributionUrl的地址指向4.6
gradle 4.6和tool 3.2.0是对应的上的。
3。继续clean,报错Unable to find CMake with version: 3.10.2 within folder:
好吧,刚才设置了CMake的默认版本3.10.2,由于降级了gradle的版本,自然不能用最新的了。把步骤一的去掉继续编辑。
这时候clean完了在rebuild,就能正常生产so文件了。
image.png
使用,JNI是JAVA和C++/C进行通信,和JAVA 和JS通信的用法差不多,毕竟是跨平台语言。