【译】NDK概述

翻译自官方文档NDK概述

NDK概述

On this page

  1. NDK使用前
  2. 介绍
  3. NDK怎样工做
  4. Native Activitie和应用程序

开始前


本指南假设已经熟悉安卓开发中的本地程序的概念.html

介绍


本节提供了NDK如何工做的高级说明。Android NDK是一组高级工具,容许你的Android应用程序中嵌入C或C++(“native code&rdquo)。在Android应用中使用本地代码的功能对于但愿执行如下一项或多项操做的开发人员尤为有用:java

  • 移植应用.
  • 重用现有库, 或提供本身的库以供重用.
  • 在某些状况下提升性能, 尤为像游戏同样的算密集的应用.

NDK如何工做


本节介绍在构建Android native应用程序时使用的主要组件, 并继续描述构建和打包过程.android

主要组件

在构建应用程序时,您应该了解如下组件:api

  • ndk-build: NDK的核心是构建脚本,而后使用ndk-build运行该脚本。这些脚本包含的内容是:
    • 能自动探测到开发环境以及应用程序项目文件肯定要构建什么.
    • 生成二进制文件.
    • 拷贝二进制文件到你的应用中.

    更多信息, 请查看ndk-build.数据结构

  • Java: Android构建进程将Java源代码生成.dex(Dalvik可执行文件)文件,这个文件在运行Android操做系统的Dalvik虚拟机(“DVM”)中运行的。 即便应用程序根本不包含Java源代码,构建进程仍然会生成一个.dex可执行文件,这个可执行文件包含了本地组件。当开发Java组件时,使用native关键字来讲明它是一个本地方法。例以下面的方法声明告诉编译器它的实现是在一个库中.

    When developing Java components, use the native keyword to indicate methods implemented as native code. For example, the following function declaration tells the compiler that the implementation is in a native library:oracle

    publicnativeint add(int  x,int  y);
  • 本地动态库: NDK从本地源代码构建这些库或.so文件.

    注意: 若是两个库分别实现了相同的方法声明,在C中会发生衔接错误, "签名"意味着方法名惟一。在C++中, "签名"意味着不只方法名称,还意味着其参数名称和类型.app

  • 本地静态库: NDK还能够构建静态库或.a文件,你能够将其连接到其余库.
  • Java本地接口(JNI): JNI是Java和C ++组件彼此通讯的接口.本指南假设知识JNI; 有关它的信息,请参阅 Java Navive接口规范.
  • 应用二进制接口(ABI): ABI准确地定义了应用程序的机器代码在运行时与系统交互。NDK根据这些定义构建.so文件。 不一样的ABI对应于不一样的体系结构:NDK包括对ARMEABI(默认),MIPS和x86的ABI支持。 有关更多信息,请参阅ABI管理.

如下两个项目只须要使用ndk-build 脚本进行构建,以及使用 ndk-gdb脚本进行调试。框架

  • Android.mk: 你必须在 jni目录中建立一个 Android.mk配置文件。ndk-build脚本将会查看这个文件,他定义了模块及名称,要编译的源文件,衔接标志和库。.
  • Application.mk: 此文件列举和描述应用程序须要的模块。此信息包括:
    • 编译用给于特定平台使用ABI.
    • 工具链.
    • 要包括的标准库(静态和动态STLport或默认系统).

流程

开发Android Native应用程序的通常流程以下:ide

  1. 设计应用程序, 决定Java中实现哪些部分, 以及本地代码实现哪些部分.

    注意: 虽然能够彻底避免Java,你会发现Android Java框架对于包括控制显示和UI在内的任务很是有用.函数

  2. 像建立其它安卓项目同样建立安卓项目.
  3. 若是你只开发一个纯native应用程序,请在AndroidManifest.xml中声明NativeActivity类。有关详细信息,请参阅Native Activities和应用程序.
  4. 建立一个描述本地库的Android.mk文件,这个文件包含了在"JNI"目录下用于编译的名称,标识,衔接库和源文件.
  5. 或者,你能够建立一个Application.mk文件配置相应的ABI,工具链,发布/调试模式和STL。若是你没有任何配置,分别使用如下默认值:
    • ABI: armeabi
    • Toolchain: GCC 4.8
    • Mode: Release
    • STL: system
  6. 将原生代码放在项目的 jni目录下.
  7. 使用ndk-build编译本地库(.so, .a).
  8. 构建Java组件,生成可执行文件.dex文件.
  9. 将全部内容打包成APK文件,其中包含.so, .dex以及运行应用程序所需的其余文件.

Native Activities和应用程序


Android SDK提供了一个帮助类NativeActivity, 它容许你写一个彻底的NativeActivityNativeActivity处理Android框架和你的本地代码之间的通讯,因此你没必要让它成为派生类或调用它的方法。你只须要在AndroidManifest.xml文件中声明你的应用程序是native应用程序。.

使用NativeActivity的Android应用程序仍然在其本身的虚拟机中运行,其它应用程序在沙盒中运行。你仍然能够经过JNI访问Android框架API,在某些状况下,例如对于传感器,输入事件,资源文件,NDK提供本地接口调用,而没必要经过JNI调用。有关此类支持的详细信息,请参阅Android NDK Native APIs..

不管您是否正在开发native Activity, 咱们建议你使用传统的Android构建工具建立项目。这样作能确保构建和打包的应用程序是正确构造的.

Android NDK为您提供两种选择来实现native activity:

  • native_activity.h头文件定义了NativeActivity类的native版本,它包含建立Native Activity所需的回调接口和数据结构。由于你应用程序的主线程处理回调,你的回调实现不能阻塞,若是回调实现阻塞,你可能会收到ANR(应用程序不响应)错误,由于您的主线程没有响应,直到回调返回。.
  • native_activity.h接口基础上, android_native_app_glue.h文件定义了一个静态辅助库。它产生另外一个线程处理事件循环中的回调或输入事件。将这些事件移动到单独的线程防止任何回调阻塞你的主线程。.

<ndk_root>/sources/android/native_app_glue/android_native_app_glue.c 源文件是可用的, 容许你修改实现.

有关如何使用此静态库的更多信息,请查看native-activity示例应用程序和文档。 进一步阅读能够查看在<ndk_root>/sources/android/native_app_glue/android_native_app_glue.h文件中的注释.

使用native_activity.h接口

使用native_activity.h接口实现一个native activity

1.在你项目的根目录下建立一个jni目录。此目录存储全部本地代码.

2.在在AndroidManifest.xml文件中声明native activity文件中声明native activity.

   由于你的应用程序没有Java代码,请将android:hasCode设置false.

<applicationandroid:label="@string/app_name"android:hasCode="false">

   你必须设置activity标记(android:name属性)为NativeActivity.

<activityandroid:name="android.app.NativeActivity"
            android:label="@string/app_name">

       注意: 你能够建立一个NativeActivity的派生类,这是要把ndroid:name属性值设为派生类的类名.

  meta-data标签的android:value属性指定为动态库的名称, 他包含了应用程序的入口点(例如C/C++的main函数),库名省略lib前缀和.so后缀.

<meta-dataandroid:name="android.app.lib_name"
            android:value="native-activity"/>
            <intent-filter>
              <actionandroid:name="android.intent.action.MAIN"/>
              <categoryandroid:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
          </activity>
        </application>
      </manifest>

 

3.为native activity建立一个文件,并实如今 ANativeActivity_onCreate变量中命名的函数。当native activity开始运行时应用程序将调用这个函数。这个函数相似于C/C++中的main函数,它接收一个指向ANativeActivity结构的指针,该结构体包含了各类须要你编写实现的函数指针。在ANativeActivity->callbacks中的回调函数指针设置为回调的实现.

4.将ANativeActivity->instance字段设置为你想使用的任何特定数据实例的地址.

5.在Activity启动前能够实现你想作的其它一些工做.

6.在ANativeActivity->callbacks.中设置实现的其他回调,有关调用回调的更多信息,请查看 Activity生命周期..

7.开发应用程序的其他部分.

8.在项目的jni/目录中建立一个Android.mk file文件,描述本地模块信息以便构建系统编译。有关详细信息,请参阅Android.mk.

9.若是你有一个Android.mk文件, 使用ndk-build命令编译本地代码.

    $ cd <path>/<to>/<project>
    $ <ndk>/ndk-build

10.像以往同样构建和安装你的Android项目。若是您的本地代码在jni/目录中,构建脚本会自动将构建的.so文件打包到APK中.

相关文章
相关标签/搜索