美文网首页编程设计之Android
NDK编程--环境搭建与开发流程

NDK编程--环境搭建与开发流程

作者: theFullHorizon | 来源:发表于2017-03-26 19:57 被阅读63次

    开发环境搭建

    • Windows下Eclipse+NDK+Cygwin方式:NDK r7之前的版本,必须要安装Cygwin才能使用NDK。而在NDKr7开始,Google简化了这个过程,在Eclispe中为NDK提供了一个ndk-build.cmd的脚本,就可以直接利用这个脚本编译,而不用再安装Cygwin(Cygwin的作用就是在Windows下模拟Linux环境)了。只需要为Eclipse Android工程添加一个Builders,而为Eclipse配置的builder,其实就是在执行Cygwin,然后传递ndk-build作为参数,这样就能让Eclipse自动编译NDK了,这就简化了我们的开发流程。
    • Windows下eclipse+NDKBundle+Ant:Windows下Eclipse使用ndk-build方式构建NDK开发环境
    • Android Studio 2.3+CMake(AS NDK开发默认的编译脚本)方式

    不得不感慨下,Google对NDK的支持越来越好,到上面提到的第三种方式时,NDK的开发,已经不需要你在环境方面麻烦了。使用CMake方式创建的支持DNK的项目大概长这样

    Paste_Image.png

    这样方式下,在JNICall中新建一个本地方法然后“Make Project”,Gradle自动会使用CMake脚本创建本地方法对应的头文件到native-lib.cpp文件中。这样就可以将更多注意力放在业务相关的C/C++开发上面。

    ndk-build脚本方式下通用开发流程

    1. 在类中定义native方法
    public class JNIUnit {
        public static native String getStringFormC();
    }
    
    1. 使用javac命令或者AS的编译工程,生成.class文件
    2. 使用javah命令将生成.class文件 --> .h头文件
    cd class文件所在目录
    javah -jni 包名.类名(如com.ns.jnistudy.JNICall)
    生成文件 com_ns_jnistudy_JNICall.h如下
    /* DO NOT EDIT THIS FILE - it is machine generated */
     _#include <jni.h>
    ...
    extern "C" {
    //注意到函数名完全按照:java_pacakege_class_mathod 形式来命名。
    //Class:     com_example_hellojni_HelloJni
    //Method:    stringFromJNI
    //Signature: ()Ljava/lang/String;
    JNIEXPORT jstring JNICALL Java_com_ns_jnistudy_JNICall_getStringFormC
      (JNIEnv *, jobject);
    ...
     }
    ...
    
    1. 将上述文件移动到的项目的jni目录下并实现.h文件对应的.c文件
    JNIEXPORT jstring JNICALL Java_com_ns_jnistudy_JNICall_getStringFormC
      (JNIEnv *, jobject){
        return (*env)->NewStringUTF(env,"just have a test");
    }
    
    1. 在jni目录下增加Android.mk和Application.mk文件,关于这两个文件的含义以及如何配置参见NDK编程--鸟瞰
    2. 环境配置
      在 file ->project structure 中增加 ndk的路径,或者在local.properties 中增加ndk路径。在 gradle.preperties 中增加android.useDeprecatedNdk=true
      修改build.gradle在 defaultConfig 节增加如下配置
      ndk {
      moduleName "NdkJniDemo" //生成的so库的名字
      abiFilters "armeabi", "armeabi-v7a", "x86"//ABI平台
      }
      配置完成之后,当程序构建时,Gradle(一种自动化构建工具,如完成编译,打包,测试等功能)so文件打包进APK中。
    3. cd到ndk目录下执行ndk-build命令(ndk-build把.c文件编译,链接生成各平台对应的.so文件)
    4. 在程序的入口处(Application或者MainActivity或定义本地方法的类中)
    static {
            System.loadLibrary("so库名字");
        }
    

    注意:第3步与第6步使用了javah和ndk-build命令,可以将命令配置成eclipse工具将命令配置成Android Studio工具

    运行时Java通过JNI调用流程

    • 当本地放在所在的类被第一次加载的时候,静态代码块会先行加载。
    • 调用的时候通过本地方法调用so文件的C/C++实现

    关于ndk-build与cmake:

    NDK本身是用来Android下编译C/C++代码的一个编译器和库的集合。这两个家伙都是基于NDK的编译系统(编译脚本),使用项目里的Java代码,将本地代码编译到共享库中,两个门干的事同一件事,解决的是同一个问题。ndk-build是NDK的包含的编译系统,使用Android.mk;cmake使用CMakeLists.txt,在你的Module app的build.gradle中你可以看到这句话

    externalNativeBuild {
            cmake {
                path "CMakeLists.txt"
            }
    }
    

    那有哥们或者妹子就不同意了,既然都一样,该如何选呢?ok,这问题Google已经帮我们做选择了,AS默认是支持CMake。且CMake脚本在非Android开发者中很流行。CMake的主要便利在于你可以使用一套编译文件构建所有的目标平台(Android,Linux,Windows,IOS,etc)。

    但是Google帮我们做了很多开发效率上的改进,但是们仍需要知道DNK开发背后的逻辑,这里以ndk-build脚本的角度来讲。

    参考

    NDK Official tutorials
    Add C and C++ Code to Your Project
    Android NDK--everything you need to know
    windows下Eclipse+NDK bundle开发
    windows下Android Studio+NDK bundle开发

    相关文章

      网友评论

      • itarbo:我直接新建一个项目,支持c++,然后目录跟你这个一样,build的时候报错,不通过:
        Error:A problem occurred configuring project ':app'.
        > executing external native build for cmake E:\githubCode\JniTest\app\CMakeLists.txt

      本文标题:NDK编程--环境搭建与开发流程

      本文链接:https://www.haomeiwen.com/subject/ooskottx.html