这里我借着android安全黄皮书,来做一遍NDK的相关开发教程,只是为了记录下过程,同时如果遇到了什么问题也可以,及时的记录并解决。! Note:原本我想照着小黄书上的过程来操作,但是书上提供的方法是基于VC6.0的,无奈上网找教程,但在实践的过程中一直都不成功,最后在官网找到了方法。因此我主要是按着官网的来。 官网链接
按着官网上,添加C/C++代码可以有两种方法,ndk-build或者是CMake外部工具,我是这么理解的。如果你直接在AS中编写C/C++代码那么选择CMake工具来构建。如果你在外部编写C/C++代码,并生成了so/dll文件那么使用ndk-build进行构建。 当然我这里使用CMake外部工具进行构建的,所有的代码均在AS中完成。 步骤一: 首先我们需要创建支持C/C++的新项目(我觉得我就是因为这一点,导致刚开始时一直报错),默认是使用CMake工具,另外也有其它的一些选项,不过这里用不到。 这里可以先建立一个Basic Activity项目,可以简单的看一下项目的结构。如果能看懂,基本上就不用看我这篇文章了。 步骤二: 接下来我们可以看一下,项目的结构,将Android视图改为Project视图。 可以看到main下有个cpp目录,里面默认创建了一个native-lib.cpp我们在其中添加我们的C代码即可。但这时需要使用Jni的写法才行。语法我就不多介绍了。 步骤三: 接下来再来看一下CMakeLists.txt文件,这个是编译参数的文件。 官方有具体的说明官网链接 我简单的说明一下。
add_library( # Sets the name of the library. native-lib # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). src/main/cpp/native-lib.cpp )这个部分用来标明库的名称和C源文件的路径,当然也可以自行添加。
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 )find_library用于寻找NDK中的库,就是一些编译好的库,我们可以直接调用其中的API函数。 步骤四: 在需要添加C代码的类中,如class JniDemo中
static { System.loadLibrary("native-lib"); }用于加载一个库。
public native static String sayHello();声明native函数的格式。 步骤五: 通常来说具体的C实现是最后编写的,先确定那部分功能需要C去实现,定义好函数头后,最后再来编写具体的实现代码。
extern "C" //用于导出,如果需要导出多个,使用{} JNIEXPORT jstring JNICALL Java_com_code_jsk_test_main_sayHello( JNIEnv * env, jobject obj){ printf("This is the printf!"); return env->NewStringUTF("This is HelloWorld from !\n"); }可以看出来,函数头往往会很长! 当然如果你想偷懒,其实也是有办法的。前提是你必须很明确自己的需求。 首先声明native代码。 还是建议新建一个简单类,非活动类如下:
public class TestDemo { public native static String JniTest(); }简单的创建一个类即可,不需要写完。接着编译module app 这时会生成相应的class文件。接着就需要使用javah工具(这里需要配置好环境变量) 使用AS中的Terminal,到如下路径。 接着使用如下命令:
javah -d jni -classpath <sdk中android.jar的路径>;..\..\build\intermediates \classes\debug com.code.jsk.test.TestDemo (具体的class文件的路径)-d jni 是生成的目录的名称,当然可以是其它路径,但是我仅仅是为了用于生成头文件。我这里就是用了cpp目录,最终会在cpp目录下生成一个.h文件。 可以看到其中有预编译好的函数头。接下的处理方法有很多…….. 基本上就是这样,最后再次运行即可。 其实CMakeLists.txt中的参数最终还是会传递到build.gradle中
终于很艰难的实现了目的,网上有很多教程,但是没有一个能照着教程一步步做成功的,总是会在一些细节的地方缺少些什么,但对于新手来说这些细节往往是最难把握的地方。 静下心来,不要烦躁,终有所获!
