JNI编程从入门到放弃
由于开发环境的不断更新 学习JNI编程和以前文章不太一样便写了这篇文章
本文假定读者已经配好开发必须环境包括NDK新人第一次发帖 写的比较新手 若有不当之处 还望指出
首先和平常一样 打开Android Studio 新建一个工程
命名如下点击finish等待Android Studio工程新建完成新建完成后如图此时为编程方便点击切换模式为了完成编程工作还需要两个sdktool
点击此处打开SDKManager
下载Cmake和LLDB
到此JNI编程的前期工作就做好了
现在正式开始编程
在此处右键 新建一个类
类名随意我就叫它JNI吧
在其中添加如下代码
public class JNI {
//加载so库
static {
System.loadLibrary("JniTest");
}
//native的方法
public static native String sayHello();
}①处为加载的so文件的名字最后生成的so文件名为lib+此名字
②处为里面的一个方法名
保存后 打开终端
切换到java文件所在目录输入javac -encoding UTF- 8 JNI.java
其中-encoding UTF-8是由于我们输入了中文需要指定编码格式
如果没有中文可忽略
执行完毕后会在当前文件夹下生成一个JNI.class文件
然后切换到java目录下输入javah -jni 包名.类名 如图
这里输入javah -jni com.example.a0xe4s0n.jniexample.JNI
执行成功后会在java文件夹下生成一个.h 文件 如图
为了调用该方法 我们还需要新建一个JNI文件夹
在main文件夹上右键
点击finish 即可完成创建
在JNI文件夹上右击 新建main.c
将刚才生成的.h文件的内容复制进去 并更改实现返回字符串
代码如下
JNIEXPORT jstring JNICALL Java_com_example_a0xe4s0n_jniexample_JNI_sayHello(JNIEnv *env, jclass jobj)
{
return (*env)->NewStringUTF(env,"Hello! This is by 0xE4s0n!");
}
然后打开app文件夹注意是app文件夹下的build.gradle文件
在defaultConfig节点里添加以下代码
注意这里的moduleName,是我们在之前自己编写的类里面加载的so库名
ndk {
moduleName "JniTest"
ldLibs "log", "z", "m"
abiFilters"armeabi-v7a", "x86"
}
在defaultConfig节点下加入以下代码:
// 使用Cmake工具 externalNativeBuild { cmake { cppFlags "" //生成多个版本的so文件 abiFilters 'arm64-v8a','armeabi-v7a','x86','x86_64' } }
在android节点下加入以下代码:
// 配置CMakeLists.txt路径externalNativeBuild { cmake { path "CMakeLists.txt"// 设置所要编写的c源码位置,以及编译后so文件的名字 }}
在根目录gradle.properties下面加上:
android.useDeprecatedNdk=true意思就是允许使用低版本的NDK
然后再app目录下新建CMakeLists.txt文件
右键app文件夹
添加如下代码
# 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文件名称.
JniTest
# Sets the library as a shared library.
SHARED
# 设置这个so文件为共享.
# Provides a relative path to your source file(s).
# 设置这个so文件为共享.
src/main/jni/main.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.
# 制定目标库.
JniTest
# Links the target library to the log library
# included in the NDK.
${log-lib} )
这里的代码需要对应自己的工程
然后编辑MainActivity的代码实现JNI函数的调用
调用JNI函数实现成功
到此完成JNI编程
至于看会飞的丑小鸭前辈的文章 需要新建一个空白文件
我没有新建也完成的编程可能开发环境不同的原因
参考资料 https://www.52pojie.cn/thread-706568-1-1.html 等
全村儿人希望 发表于 2018-12-21 16:52
JNI是做什么的,写手机端的?
JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++) 你这个过于复杂了吧,现在的Android studio本身就可以创建支持C/C++的项目,并且相关配置都会弄好,完全没有必要去关心里面这些东西 放弃为时过早,{:301_983:} 感谢分享 JNI是做什么的,写手机端的? 加油~爱你哦 安卓app也可以加壳吗,第一此听说,看来我还需要多学习学习
KSTG_茶飘香 发表于 2018-12-21 17:32
安卓app也可以加壳吗,第一此听说,看来我还需要多学习学习
有啊 还挺复杂的 感谢分享