当前位置:首页 > 嵌入式培训 > 嵌入式学习 > 讲师博文 > NDK环境配置

NDK环境配置 时间:2018-09-25      来源:未知

Android 原生开发包NDK(Native Delopment kits)将用于Android平台上的C++开发。Android NDK是Android软件开发包(SDK)的相关工具集,用来扩展Android SDK的功能,从而是开发人员能够使用机器代码生成的编程语言(如C、C++和汇编语言)实现一些对代码行要求较高的模块并将这些模块嵌入到Android应用程序中。

众所周知,Android程序运行在Dalvik虚拟机中,NDK允许用户使用类似C / C++之类的原生代码语言执行部分程序。

Android NDK不是一个单独的工具:它是一个包含API、交叉编译器、链接程序、调试器、构建工具、文档和实例应用程序的综合工具集。

1、以下是Android NDK的一些主要组件:

ARM x86和MIPS交叉编译器

构建系统

java原生接口头文件

C库

Math库

POSIX线程

小的C++库

Zlib压缩库

Android 日志库

Android 像素缓冲区库

Android原生应用APIs

OPENGL ES 3D图形库

OPENSL ES 原生音频库

OpenMAX AL 小支持

2、Android NDK的结构

ndk-build :该shell脚本是Android NDK 构建系统的起始点,

ndk-gdb:该shell脚本允许用GNU调试器调试原生组件。(第五章)

ndk-stack:该shell脚本可以帮助分析原生组件崩溃时的堆栈追踪号(第五章)

build:该目录包含Android NDK构建系统的所有模块,本章将详细介绍Android ndk构建系统

platforms:该目录包含了支持不同Android目标版本的头文件的库文件

Androidndk构建系统会根据具体的Android八本自动引用这些文档。

samples:该目录包含了一些实例应用程序,这些程序可以体现Android NDK的特性,对应学习android ndk的特性会很有帮助

source:

该目录包含目前Android NDK 支持不同目标机体系机构的交叉编译器,Android 目前支持ARM X86 MIPS等体系结构

Android NDK 的构建系统根据选定的体系结构使用不同的交叉编译器。

3、为何要用到NDK?

概括来说主要分为以下几种情况:

1. 代码的保护,由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。

2. 在NDK中调用第三方C/C++库,因为大部分的开源库都是用C/C++代码编写的。

3. 便于移植,用C/C++写的库可以方便在其他的嵌入式平台上再次使用。

JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的。例如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少要保证本地代码能工作在任何Java 虚拟机环境下。

JNI是java程序设计语言功能的强特征,它允许java类的某些方法原生实现,同时让他们能够像普通的java方法一样被调用和使用。这些原生方法也可以使用java对象,使用方法与java代码使用java对象的方法相同。原生方法可以创建新的java对象或者使用java应用程序创建的对象,这些java应用程序可以检查,修改和调用这些对象的方法执行任务。

JNI的副作用:

一旦使用JNI,JAVA程序就丧失了JAVA平台的两个优点:

1、程序不再跨平台。要想跨平台,必须在不同的系统环境下重新编译本地语言部分。

2、程序不再是绝对安全的,本地代码的不当使用可能导致整个程序崩溃。一个通用规则是,你应该让本地方法集中在少数几个类当中。这样就降低了JAVA和C之间的耦合性。

什么场合下应该使用JNI:

当你开始着手准备一个使用JNI的项目时,请确认是否还有替代方案。像上一节所提到的,应用程序使用JNI会带来一些副作用。下面给出几个方案,可以避免使用JNI的时候,达到与本地代码进行交互的效果:

1、JAVA程序和本地程序使用TCP/IP或者IPC进行交互。

2、当用JAVA程序连接本地数据库时,使用JDBC提供的API。

3、JAVA程序可以使用分布式对象技术,如JAVA IDL API。

这些方案的共同点是,JAVA和C处于不同的线程,或者不同的机器上。这样,当本地程序崩溃时,不会影响到JAVA程序。

下面这些场合中,同一进程内JNI的使用无法避免:

1、程序当中用到了JAVA API不提供的特殊系统环境才会有的特征。而跨进程操作又不现实。

2、你可能想访问一些己有的本地库,但又不想付出跨进程调用时的代价,如效率,内存,数据传递方面。

3、JAVA程序当中的一部分代码对效率要求非常高,如算法计算,图形渲染等。

总之,只有当你必须在同一进程中调用本地代码时,再使用JNI。

JNI的演化:

JDK1.0包含了一个本地方法接口,它允许JAVA程序调用C/C++写的程序,许多第三方的程序和JAVA类库。如:java.lang,java.io,java.net等都依赖于本地方法来访问底层系统环境的特征。

不幸的是,JDK1.0中的本地方法有两个主要问题:

1、本地方法像访问C中的结构(structures)一样访问对象中的字段。尽管如此,JVM规范并没有定义对象怎么样在内存中实现。如果一个给定的JVM实现在布局对象时,和本地方法假设的不一样,那你就不得不重新编写本地方法库。

2、因为本地方法可以保持对JVM中对象的直接指针,所以,JDK1.0中的本地方法采用了一种保守的GC策略。

JNI的诞生就是为了解决这两个问题,它可以被所有平台下的JVM支持:

(1)每一个JVM实现方案可以支持大量的本地代码。

(2)开发工具作者不必处理不同的本地方法接口。

(3)本地代码可以运行在不同的JVM上面。

JDK1.1中第一次支持JNI,但是,JDK1.1仍在使用老风格的本地代码来实现JAVA的API。这种情况在JDK1.2下被彻底改变成符合标准的写法。

JNI的设计目的:

标准的java类库可能不支持你的程序所需的特性。或许你已经有了一个用其他语言写成的库或程序,而你希望在java程序中使用它。

你可能需要用底层语言实现一个小型的时间敏感代码,比如汇编,然后在你的java程序中调用这些功能。

1、AndroidC++开发环境主要有以下几部分构成:

Android软件开发包(SDK)

Android原生开发包(NDK)

Ecplise上的Android开发工具 ADT插件

java开发包

GNU Make构建系统

ecplise IDE

2、

(1)首先我们安装java环境

(2)安装ecplise开发环境

(3)给ecplise添加ADT插件

(4)安装SDK,NDK与ecplise进行关联

(5)GNU make构建系统

3、配置开发环境

在ecplise中配置SDK,NDK

为了先给大家展示一下什么样的项目为一个ndk项目,我们选择在samples目录下包含了Android NDK安装程序自带的示例应用程序。现在可以使用其中的示例应用程序。

导入方式:File-->import-->Android-->Existing Android code into workspace导入NDK路径下的samples-->helloJni项目

成功如下所示:

导入之后,只将项目作为Android java 项目导入,为了让构建流包含原生组件,需要手动添加原生支持,添加方式:

项目上右键--->Android ToolS--->add native support-->后点击确定

添加成功:之后打开模拟器运行

运行方式:

在项目上右键-->run as--->Android application

上一篇:使用KGDB在QEMU上调试内核

下一篇:NDK项目开发实例

热点文章推荐
华清学员就业榜单
高薪学员经验分享
热点新闻推荐
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2022 北京华清远见科技集团有限公司 版权所有 ,京ICP备16055225号-5京公海网安备11010802025203号

回到顶部