近期在学习so相关的编程,发现每次写了新方法之后,还需要到相对应的java文件目录下执行一些java脚本,帮助我们生成在jni中会用到的一些C++的头文件。后来觉得每次这么写太麻烦,有没有简单点的处理办法呢,后来发现AndroidStudio有一个叫External Tools的东西,可以帮助我们实现。
1.首先,如果想要学习NDK的话,那么相关的NDK的环境肯定要先配置好的。如果你已经配置好的话,那么项目框架下的ndk-bundle会显示出来,如果没有,也没关系,AS提供有自动下载的功能,就在显示路径的地方,到时候点击就可以下载了。
2.其次,我们先在自己的工程目录的main目录下创建一个名为jni的目录,用于存放我们的C++代码。
3.声明我们将要写在C++中的方法,这个方法将输出一个hello world。
4.接下来,本来我们的工作是进入到MyJni.java的目录下执行javah的命令,现在我们使用另外一种方法实现,配置External Tools。
5.配置完了javah,那么我们接下来配置ndk相关的东西。
首先配置一下ndk build clean 命令
然后配置ndk-bundle的命令
最终的结果就是我们的External Tools会多出三个选项,如下图所示
6.配置了一大堆,怎么用呢?这是个问题,现在我们来看一下重点,用法:右键我们的MyJni.java这个文件会出下如下选项:
点击之前首先要Make project一下,然后再javah,如果之前路径都没问题的话,那么会显示:
[Creating file RegularFileObject[com_example_administrator_myapplication2_MyJni.h]]
Process finished with exit code 0
代表已经生成头文件,在你的moudle/src/main/jni路径下
7.之后我们来写两个文件Android.mk和Application.mk
Application.mk(最新版本的NDK需要新增APP_PLATFORM,且已经不支持armeabi)
APP_MODULES := JniTest
APP_ABI := armeabi-v7a
APP_PLATFORM := android-16
文件中的JniTest就是我们生成so的名字,armeabi-v7a就是我们要编译出来api的版本,可以有多个。
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JniTest
LOCAL_SRC_FILES =: main.cpp
include $(BUILD_SHARED_LIBRARY)
文件中的main.cpp就是我们创建的实现头文件的C++源码:
//
// Created by Administrator on 2018/7/15.
//
#include "com_example_administrator_myapplication2_MyJni.h"
/*
* Class: com_example_administrator_myapplication2_MyJni
* Method: sayHello
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_administrator_myapplication2_MyJni_sayHello
(JNIEnv *env, jclass jobj) {
return (*env).NewStringUTF("hello world");
}
很简单的实现,分为两部,第一引入头文件,第二返回一个hello world字符串。
8.写好了之后我们就可以开始编译so,来到最后一步了是不是很开心?
执行完ndk-build命令之后,so文件已经在我们项目中生成了
9.调用so方法,终于到最后了,也是最简单的一步。
然后就可以看到日志,打印了,赶快运行一下吧。
参考:
1.https://blog.csdn.net/xiaozhu0922/article/details/78835144
2.https://blog.csdn.net/huangximin1990/article/details/50441400
Tips:学习的过程中也遇到了困难,给大家分享下
1.mac的情况下D:\AndroidStudio\ndk-bundle\ndk-build.cmd最后的.cmd是不需要的
2.在配置External Tools的过程中,双$符号内的都是变量,可以通过后面的Insert Macros查找添加,手动写貌似没用
3.在使用javah是报了一个Exception in thread "main" java.lang.IllegalArgumentException: Not a valid class name: Files\Android\Android,看了下是路径中含有了空格,去掉就Ok。
谢谢大家