《Android应用开发与系统改造实战》——1.5节Android NDK开发环境搭建-阿里云开发者社区

开发者社区> 异步社区> 正文

《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程序中调用就可以了。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
《Android应用开发入门经典(第3版)》——第1.1节建立开发环境
本节书摘来自异步社区《Android应用开发入门经典(第3版)》一书中的第1章,第1.1节建立开发环境,作者 【美】Carmen Delessio , Lauren Darcey , Shane Conder,更多章节内容可以访问云栖社区“异步社区”公众号查看 1.1 建立开发环境 Android应用开发入门经典(第3版) 要进行Android开发,首先需要创建一个可工作的开发环境。
1564 0
基于Spark的机器学习实践 (三) - 实战环境搭建
0 相关源码 1 Spark环境安装 ◆ Spark 由scala语言编写,提供多种语言接口,需要JVM ◆ 官方为我们提供了Spark 编译好的版本,可以不必进行手动编译 ◆ Spark安装不难,配置需要注意,并且不一定需要Hadoop环境 下载 解压 tar zxvf spark-2.
1048 0
10.Eclipse下Ndk开发(ffmpeg native 方式播放视频,万能解码(SurfaceView, 播放音频,)
(创建于2018/1/26) 遇到的问题 遇到一个很棘手的问题,在Eclipse上引入两个头文件报错 #include #include 右键->Porperties->C/C++General->Paths and Symbols中可以看到 987671.
1134 0
+关注
异步社区
异步社区(www.epubit.com)是人民邮电出版社旗下IT专业图书旗舰社区,也是国内领先的IT专业图书社区,致力于优质学习内容的出版和分享,实现了纸书电子书的同步上架,于2015年8月上线运营。公众号【异步图书】,每日赠送异步新书。
12049
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载