【译】NDK概述

摘要:
翻译自官方文档NDK概述NDK概述OnthispageNDK在使用NDK之前,介绍NDK如何工作NativeActivity和应用程序本指南假设您熟悉Android开发中本地程序的概念。简介本节提供了NDK工作原理的高级描述。

翻译自官方文档NDK概述

NDK概述

On this page

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

开始前


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

介绍


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

  • 移植应用.
  • 重用现有库, 或提供自己的库以供重用.
  • 在某些情况下提高性能, 尤其像游戏一样的算密集的应用.

NDK如何工作


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

主要组件

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

  • 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:

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

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

  • 本地静态库: 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应用程序的一般流程如下:

  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中.

免责声明:文章转载自《【译】NDK概述》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Dubbo常用功能02--protocol协议ubuntu下linux内核源码阅读工具和调试方法总结下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ffmpeg综合应用示例(三)——安卓手机摄像头编码

本文的示例将实现:读取安卓手机摄像头数据并使用H.264编码格式实时编码保存为flv文件。示例包含了 1、编译适用于安卓平台的ffmpeg库 2、在java中通过JNI使用ffmpeg 3、读取安卓摄像头数据并在后台线程中使用ffmpeg进行编码的基本流程 具有较强的综合性。 编译适用于安卓平台的ffmpeg库 平时我们编译ffmpeg类库都是在x86平...

Android 4.0 SDK的离线方式安装(转)

转自:http://networking.ctocio.com.cn/110/12195610.shtml  作 为一个IT技术人员,迫不及待地就奔向了http://developer.android.com去看看有没有新的SDK公布出来,当时是上午,没见到 有更新,心想一定是若干天后才会发布。没想到同事下午告诉我,新版的SDK已经发布了。当时是临下班,...

Android开发笔记(十六)——Activity的4种启动模式

AndroidManifest 中比较重要的一个属性是 launchMode 启动模式: Acyivity的 android:launchMode 四个属性: standard:标准模式,默认 singleTop:Task栈顶复用模式(栈是先进后出,当我们启动一个Activity,如果这个目标Activity位于栈顶,不会创建一个新的实例,而是会直接...

NDK开发之ndk-build命令详解

毫无疑问,通过执行ndk-build脚本启动android ndk构建系统。 默认情况下,ndk-build脚本在工程的主目录中执行,如: 我们可以用使用-C参数改变上述行为,-C指定工程的目录,这样我们就可以在任何目录执行ndk-build脚本了。 如果源文件没有被修改,那么android ndk构建系统不会重新构建目标,这时我们可以使用参数-B来...

win10下ndk编译arm可执行体

编译参考文章 http://blog.csdn.net/john_1984/article/details/12622215 一、编写soLoader主文件 soLoader.c内容: #include <stdio.h>typedef int (*MAIN_FN)(int,char**); int main(int argc,char*arg...

【转载】Android属性动画和视图动画的区别

提起动画首先想到的是动画片,童年最爱的黑猫警长,葫芦娃,邋遢大王,大脸猫和蓝皮鼠,四驱兄弟,七龙珠等等,当时觉着好神奇,他们是怎么动的呢。动画其实就是一帧帧的画面顺序播放,只要画面切换的够快,会我们眼中形成视觉残留的效果,人眼不会感觉到突兀也就会认为画面是连续运动的,至于24帧什么的这里就不说了,现在的手机普遍支持60帧每秒,微鲸的vr设备好像87帧每秒...