我用的是Android studio集成Android的NDK
首先先看一下大概步骤:
- 1,下载NDK
- 2,NDK的环境搭建
- 3,Demo实例之调用本地无参方法直接返回字符串
- 4,通过javah命令获取到本地头文件
- 5,生成jni文件夹。用于存放.h和.c文件
- 6,创建并编写.c文件
- 7,as中配置生成so文件的信息。
- 8,解决so文件生成失败
- 9,结果演示
一:下载NDK
1:NDK的下载我采用的是Android studio自带的ndk
然后在SDK中找到NDK,下载不用翻墙下载,直接下载就可以了。
2:配置as中ndk路径。如果ndk路径没有自动添加,则点击select即可。并在local.properties配置文件中检查是否正确配置路径。
如果是直接采用上面的方式下载,下面这个路径是自动会生成的用户不用在添加
3、设置as。将ndk版本差异检测过滤掉,要不然项目无法编译。添加:android.useDeprecatedNdk=true
二:NDK的环境搭建
进入环境变量
新建系统变量NDK_ROOT并且把我们刚刚生成的ndk环境变量路径复制进去
(我的是C\:\\Users\\Administrator\\AppData\\Local\\Android\\Sdk\\ndk-bundle)根据Android studio中local.properties中的ndk.dir的路径写。上面也有对应的截图
然后在path中加上路径(或者也可以直接把NDK的路径直接写在path里面,这样就可以不用创建NDK_ROOT了)
dos下命令:ndk-build;出现以下信息说明配置成功
如果还是显示不是本地命令的话就是环境没有配置对,如果重新配置一定要把dos窗口关掉然后在重新开启。
三、Demo实例之调用本地无参方法直接返回字符串
直接在layout中添加一个按钮Button控件,用于点击调用本地方法:
二 在MainActivity中获取该控件并注册它的点击监听器
Button java2C=findViewById(R.id.java2C);
java2C.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String result =new Java2CJNI().java2C();
Toast.makeText(MainActivity.this,result,Toast.LENGTH_LONG).show();
}
});
三 创建Java2CJNI类及本地方法
在我们的包下直接创建一个Java2CJNI类,并在类里创建一个java2C的本地方法:
package com.boxin.forkliftserialport;
public class Java2CJNI {
static {
System.loadLibrary("Java2C");
}
public native String java2C();
}
四 通过javah命令获取到本地头文件
在项目根目录下,进入main->java目录,全选文件目录栏,直接输入cmd命令并按回车键进入docs命令,在命令中执行javah -jni com.boxin.forkliftserialport.Java2CJNI命令: (com.boxin.forkliftserialport是包名,需要根据自己的包名改变)
(注意:首先我们一定要先set存放我们刚刚创建Java2CJNI,java的路径,否则直接javah -jni com.boxin.forkliftserialport.Java2CJNI会出现找不到文件路径的错误)
生成了com.boxin.forkliftserialport.Java2CJNI.h文件。
五、生成jni文件夹。用于存放.h和.c文件
![](https://img-blog.csdnimg.cn/20190909140655531.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NzEwNzk4,size_16,color_FFFFFF,t_70)
然后把刚刚生成的com.boxin.forkliftserialport.Java2CJNI.h移动到该目录
六、创建并编写.c文件
将步骤四中生成的.h文件移动到jni文件夹下,并创建一个.c文件来写c代码
下面的类型选择.c类型
在Java2C文件中加入以下代码(包名要根据自己的更改)
#include "com_boxin_forkliftserialport_Java2CJNI.h"
JNIEXPORT jstring JNICALL Java_com_boxin_forkliftserialport_Java2CJNI_java2C(JNIEnv *env, jobject instance) {
return (*env)->NewStringUTF(env,"I am from Native C .");
}
七、as中配置生成so文件的信息。
![这里写图片描述](https://img-blog.csdn.net/20161011150217839)
用Make Project 生成so文件,然后运行项目。
八、解决so文件生成失败
本来想做到这里应该就可以生成so文件了,但是还是不行运行了项目还是没有生成而且一直出现提示;
Flag android.useDeprecatedNdk is no longer supported and will be removed in the next
最后只能继续研究了;
大概意思就是说:
- android.useDeprecatedNdk不再支持了
- 让使用CMake or ndk-build
- 然后还有链接
解决方法:
1、先通过SDKManager下载:CMake和LLDB
2、在build.gradle的defaultConfig节点下加入:
externalNativeBuild {
cmake {
cppFlags ""
abiFilters 'arm64-v8a','armeabi-v7a','x86','x86_64'
}
}
和在Android加上
externalNativeBuild {
cmake {
path "CMakeLists.txt" // 设置所要编写的c源码位置,以及编译后so文件的名字
}
}
CMakeLists.txt文件是我们自己创建的txt文件。添加CMakeLists.txt文件到build.gradle文件同级目录下,
具体内容如下:
# 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.
#CMakeLists.txt
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
# 设置这个so文件为共享.
# Provides a relative path to your source file(s).
# 设置这个so文件为共享.
src/main/jni/Java2C.c)
# 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} )
下图中圈红色的我已经改了。使用者要根据自己生成的so文件的名称改变
最后重新运行项目终于生成了so文件了