《Android应用开发与系统改造实战》——1.5节Android NDK开发环境搭建

简介:

本节书摘来自异步社区《Android应用开发与系统改造实战》一书中的第1章,第1.5节Android NDK开发环境搭建,作者 王保卫 , 申波,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.5 Android NDK开发环境搭建
Android应用开发与系统改造实战

1.5.1 Android NDK简介
Android NDK是编译嵌入在Android应用中的原生代码(C或C++)的工具。

Android应用运行在Dalvik虚拟机上。NDK允许开发者用原生代码(C或C++)实现应用的一部分。这将给某些应用带来好处,这种方式可重用代码,而且在某些情况下可加快运行速度。

NDK提供了将C和C++源代码生成原生代码库的工具和文件;提供了将原生库嵌入apk文件的方法;提供了兼容Android1.5版本以上的原生系统头文件和库;提供了文档,示例和指引。

最新发布的NDK版本支持ARMv5TE和ARMv7-A机器指令集,提供稳定的C库头文件(C library),JNI接口和其他的库。在将来的版本中还将支持x86 instructions。

ARMv5TE机器指令可以运行在所有的包含ARM CPU的计算机上。ARMv7-A机器指令只能运行在Verizon Droid 或者Google Nexus One这种具有兼容性的CPU的机器上。这两种机器指令的不同之处在于,ARMv7-A支持硬件FPU、Thumb-2和NEON指令。你可以以其中一个或者两个为目标来设置,默认情况下是ARMv5TE,你可以通过在应用程序的Application.mk文件的开始(通过设置默认指令的类型就很容易地切换到ARMv7-A)其他的部分都不用改变。你也可以建立同时适配两种结构,并且将所有的东西都存储在最终的.apk文件中。

NDK并不适用于大部分应用。作为开发者,你应该衡量它的优缺点。很明显,用原生代码并不能自动提升性能,却增加了应用的复杂度。NDK适合用于独立的、占用内存少、占用较多CPU资源的处理,例如,信号处理、物理仿真等。简单的用C重写代码一般不会带来性能的大幅提升。不过,NDK提供了重用现有C/C++的有效途径。

Android Framework层提供了两种方法来访问本地native代码。

(1)利用Android Framework来编写应用,并且使用JNI来访问Android NDK提供的API。这项技术允许你充分利用Framework层提供的便利,而且允许你在必要的时候编写native代码。不过编写出来的应用只可以运行在Android 1.5以上的设备上。

(2)编写一个native的Activity,这个Activity允许你在native代码中实现Activity生命周期中的某个部分的回调。Android SDK提供了nativeActivity类,它可以很方便地提示你,在Activity的生命周期的某个部分,如onCreate( )、onResume( )或者onStop等时候再在native代码中实现你的回调。利用native Activity编写的应用程序必须运行在Android 2.3以及以后的系统版本平台上才可以。

注意 NDK并不能让你开发纯原生应用。Android的主要运行时仍然是Dalvik虚拟机。
NDK包含了一套交叉编译工具(编译,linkers等),它可生成Linux、OS X和Windows(用Cygwin)上的原生ARM的二进制码。

它提供了一套原生API的系统头文件(兼容今后版本)。

libc(C library)headers。
libm(math library)headers。
JNI interface headers。
libz(Zlib compression)headers。
liblog(Android logging)header。
OpenGL ES 1.1 and OpenGL ES 2.0(3D graphics libraries)headers。
libjnigraphics(Pixel buffer access)header(for Android 2.2 and above)。
A Minimal set of headers for C++ support。
OpenSL ES native audio libraries。
Android native application APIS。

NDK也提供了编译系统,可以快速编译源代码,而不用处toolchain/platform/CPU/ABI的细节问题。只需创建很短的编译文件,用来说明哪些源代码需要编译,以及编译到哪个目标Android应用,编译工具将根据此文件编译,并将生成的共享库放到对应的应用下。

重要 提示 除上述的库之外,Android 1.5的原生系统库在以后的版本有可能改变。因此,你的应用应该只适用NDK提供的库。

1.5.2 开发环境配置
1.配置命令行的编译方式

(1)Cygwin安装。

首先下载Cygwin软件,下载地址如下:

http://www.cygwin.com/setup.exe

Cygwin安装比较麻烦些,安装的快慢主要依靠网络速度。

我这里选择的是Default安装后,再安装以下模块。

make。
binutils。
gcc-core。
gcc4-core。
gdb。
GNU awk。
在搜索输入框里分别输入上面的关键字查找出来安装,如图1.43所示。


0910d2590ffecf24f65f7daf3ef31ffff5f58409

(2)NDK安装。

从官方网站上下载NDK后解压到一个目录下就可以了,解压后的绝对路径是E:/paul/developandroid/AndroidNDKDevelop/android-ndk-r5。

(3)上面的软件安装完成后,下面设置环境变量。

进入C:cygwinhomeAdministrator目录,打开目录里的.bash_profile文件,在最下面一行输入设置NDK的编译工具的目录如下:

export DK_HOME=/cygdrive/e/paul/developandroid/AndroidNDKDevelop/android-ndk-r5
(4)使用该工具的命令行进行编译NDK自带的程序。

打开已经安装好的Cygwin.exe文件,如图1.44所示。


7901e79eecc1e18dd2feea0544f2623b0c8ddae6

然后开始编译该目录下的文件。

输入命令:$NDK_HOME/ndk-build,回车后开始编译,编译完成后,会在libs目录下找到编译完成的.so文件,如图1.47所示。


9d4196df3cbd1e1a7bbcb0336ca7bb6864f78ddb


9d4196df3cbd1e1a7bbcb0336ca7bb6864f78ddb


c61bc6a1d82184d507d5f6eed1286e0dc1513cf2

安装完成后重启Eclipse就可以了。

其实运行一个NDK的例子工程后发现,CDT并不是必须的,不过至少安装CDT后并没有什么坏处。在利用NDK时,其中的C或C++文件就可以利用Android中的CDT工具进行开发。

安装CDT之前C++文件的编辑如图1.51所示。


aff67ec857aa24adea96066529510e007636aa85

1.5.3 NDK的实例开发
1.新建工程

运行Eclipse,新建一个Android Project,取名HelloJni(或者自己喜欢的其他名字,比如fxxk-jni也行)。

工程代码就从NDK/samples/hello-jni复制一份即可,记得复制jni那个目录,最终的配置目录结构如图1.53所示。


fd4918b3b32f185f868174e4907e5c9d7bc792e9

Libs目录会自动创建,如图1.53所示。

下面是各部分的代码,其中,HelloJni.java的代码如下:

public class HelloJni extends Activity { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        TextView  tv = new TextView(this);  
        tv.setText( stringFromJNI() );  
        setContentView(tv);  
    } 

    public native String  stringFromJNI(); 

    static { 
        System.loadLibrary("hello-jni"); 
    } 
}
hello-jni.c的代码如下:

#include <string.h> 
#include <jni.h> 

jstring 
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,  
                                                             jobject thiz )  
{  
    return (*env)->NewStringUTF(env, "Hello from JNI !");  
}
Android.mk的代码如下:

LOCAL_PATH := $(call my-dir)  

include $(CLEAR_VARS)  

LOCAL_MODULE    := hello-jni 
LOCAL_SRC_FILES := hello-jni.c 

include $(BUILD_SHARED_LIBRARY)
如果现在运行这个工程,就会在Android控制台看到如下错误:

java.lang.UnsatisfiedLinkError: Library hello-jni not found。

因为还没有产生那个libhello-jni.so出来。没关系,下面继续进行可以解决问题。

2.工程属性设置

打开hello-jni工程属性,选择Builders,点击New,选择Program,点击“OK”按钮,如图1.54所示。

配置如下,名字随便取一个,Location和working directory要和你的Cygwin目录一致,arguments要和工程目录一致。arguments是:

---login -c "cd /cygdrive/e/paul/developandroid/workspace21/AnroidNDKTest && $NDK_HOME/ndk-build"

其中命令第一部分e/paul/developandroid/workspace21/AnroidNDKTest是你的工程所在的目录,第二部分$NDK_HOME/ndk-Build是在cygwin下设置的环境变量,这是在使用NDK工具,如图1.55所示。


7f67d12da577ce2f9e560b55429b1f5cd8fc23b1

从上面的图片应该看得清,然后勾选其他配置如图1.56和图1.57所示。


ed4245fde2e5d9bf5e56cbba71f409b9c91171c3

当以上步骤都正确配置无误,保存配置后应该就会自动编译jni目录下的C相关代码,并输出相应的.so库文件到工程的libs目录下,libs目录会自动创建。

注意如图1.58所示,将ndk_Builder向上移动到第一位,因为C++需要先编译成.so后Java程序才能使用。


9b1a24fa623c8ae692c44aac24a30071deab9265

编译时控制台输出类似如图1.59所示。


b7954eba158200c527eae395792c8673f24b02b1

至此,我们的NDK环境搭配完毕,并且在此时,或许你对NDK有了初步的了解,能够掌握这些就可以进行NDK的开发了,用到NDK的时候一般是具有独立功能的部分,如播放器的编解码部分,可以将这部分用C++开发并生成so文件,再从Java程序中调用就可以了。

相关文章
|
11天前
|
Android开发 Swift iOS开发
深入探索iOS与Android操作系统的架构差异及其对应用开发的影响
在当今数字化时代,移动设备已经成为我们日常生活和工作不可或缺的一部分。其中,iOS和Android作为全球最流行的两大移动操作系统,各自拥有独特的系统架构和设计理念。本文将深入探讨iOS与Android的系统架构差异,并分析这些差异如何影响应用开发者的开发策略和用户体验设计。通过对两者的比较,我们可以更好地理解它们各自的优势和局限性,从而为开发者提供有价值的见解,帮助他们在这两个平台上开发出更高效、更符合用户需求的应用。
|
20天前
|
搜索推荐 前端开发 Android开发
安卓应用开发中的自定义视图实现
【10月更文挑战第30天】在安卓开发的海洋中,自定义视图是那抹不可或缺的亮色,它为应用界面的个性化和交互体验的提升提供了无限可能。本文将深入探讨如何在安卓平台创建自定义视图,并展示如何通过代码实现这一过程。我们将从基础出发,逐步引导你理解自定义视图的核心概念,然后通过一个实际的代码示例,详细讲解如何将理论应用于实践,最终实现一个美观且具有良好用户体验的自定义控件。无论你是想提高自己的开发技能,还是仅仅出于对安卓开发的兴趣,这篇文章都将为你提供价值。
|
20天前
|
JSON Java Android开发
探索安卓开发之旅:打造你的第一个天气应用
【10月更文挑战第30天】在这个数字时代,掌握移动应用开发技能无疑是进入IT行业的敲门砖。本文将引导你开启安卓开发的奇妙之旅,通过构建一个简易的天气应用来实践你的编程技能。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你宝贵的学习资源。我们将一步步地深入到安卓开发的世界中,从搭建开发环境到实现核心功能,每个环节都充满了发现和创造的乐趣。让我们开始吧,一起在代码的海洋中航行!
|
20天前
|
Android开发 Swift iOS开发
探索iOS与安卓应用开发的差异性
探索iOS与安卓应用开发的差异性
40 2
|
26天前
|
传感器 XML IDE
探索安卓应用开发:从基础到进阶
【10月更文挑战第23天】在数字化时代的浪潮中,移动应用已成为人们日常生活的延伸。本文以安卓平台为例,深入浅出地介绍了如何从零开始构建一个安卓应用,涵盖了开发环境搭建、基本组件使用、界面设计原则以及进阶技巧等关键步骤。通过实例演示和代码片段,引导读者逐步掌握安卓应用开发的核心技能,旨在激发更多开发者对安卓平台的探索热情,并为初学者提供一条清晰的学习路径。
|
20天前
|
存储 搜索推荐 Java
打造个性化安卓应用:从设计到实现
【10月更文挑战第30天】在数字化时代,拥有一个个性化的安卓应用不仅能够提升用户体验,还能加强品牌识别度。本文将引导您了解如何从零开始设计和实现一个安卓应用,涵盖用户界面设计、功能开发和性能优化等关键环节。我们将以一个简单的记事本应用为例,展示如何通过Android Studio工具和Java语言实现基本功能,同时确保应用流畅运行。无论您是初学者还是希望提升现有技能的开发者,这篇文章都将为您提供宝贵的见解和实用的技巧。
|
23天前
|
搜索推荐 开发工具 Android开发
打造个性化Android应用:从设计到实现的旅程
【10月更文挑战第26天】在这个数字时代,拥有一个能够脱颖而出的移动应用是成功的关键。本文将引导您了解如何从概念化阶段出发,通过设计、开发直至发布,一步步构建一个既美观又实用的Android应用。我们将探讨用户体验(UX)设计的重要性,介绍Android开发的核心组件,并通过实际案例展示如何克服开发中的挑战。无论您是初学者还是有经验的开发者,这篇文章都将为您提供宝贵的见解和实用的技巧,帮助您在竞争激烈的应用市场中脱颖而出。
|
25天前
|
算法 Java 数据库
Android 应用的主线程在什么情况下会被阻塞?
【10月更文挑战第20天】为了避免主线程阻塞,我们需要合理地设计和优化应用的代码。将耗时操作移到后台线程执行,使用异步任务、线程池等技术来提高应用的并发处理能力。同时,要注意避免出现死循环、不合理的锁使用等问题。通过这些措施,可以确保主线程能够高效地运行,提供流畅的用户体验。
38 2
|
29天前
|
Java API Android开发
安卓应用程序开发的新手指南:从零开始构建你的第一个应用
【10月更文挑战第20天】在这个数字技术不断进步的时代,掌握移动应用开发技能无疑打开了一扇通往创新世界的大门。对于初学者来说,了解并学习如何从无到有构建一个安卓应用是至关重要的第一步。本文将为你提供一份详尽的入门指南,帮助你理解安卓开发的基础知识,并通过实际示例引导你完成第一个简单的应用项目。无论你是编程新手还是希望扩展你的技能集,这份指南都将是你宝贵的资源。
48 5
|
29天前
|
移动开发 Dart 搜索推荐
打造个性化安卓应用:从零开始的Flutter之旅
【10月更文挑战第20天】本文将引导你开启Flutter开发之旅,通过简单易懂的语言和步骤,让你了解如何从零开始构建一个安卓应用。我们将一起探索Flutter的魅力,实现快速开发,并见证代码示例如何生动地转化为用户界面。无论你是编程新手还是希望扩展技能的开发者,这篇文章都将为你提供价值。
下一篇
无影云桌面