AndroidNDK使用分析:

在Android应用程序开发中,对于一些对性能安全要求较高的模块开发中,我们一般会使用C/C++代码来实现,或者引用一些已经实现好的C/C++库时,都需要使用JNI机制。正如上面的介绍是比较常用的,同样可以实现编写基于JNI机制访问C/C++库文件。

AndroidNDK是谷歌公司提供的开发工具集,我们可以使用它快捷得开发基于JNI机制的程序。它的几个重要的功能如下:

A、提供将C/C++源代码编译成本地库文件(编译器、连接器等)

B、提供将编译好的本地库文件插入到Android的包文件(.apk)

C、提供NDK开发相关的文档、实例及规范等

注意:

谷歌是不建议开发者使用NDK开发Android本地应用程序的,当然,这样做是可以实现的,因为Android系统的主要应用是运行在dalvik虚拟机上的Java程序,推荐多开发运行在dalvik上的程序。

NDK的功能:

如上图所示,Androidndk先编译了C/C++本地代码,并生成本地库文件,然后将其插入到Android应用程序的包当中,但调用JNI的编译本地代码的工作还需要我们来做的。

NDK安装:

在谷歌官网上下载最新的NDK包,并解压到指定的目录下,那么这个目录就作为环境变量的名字,即NDK_HOME,然后在环境变量的path中添加该NDK_HOME环境变量即可。

Cygwin安装:

在上面,我们已经安装并安装了Cygwin了,在这里简单介绍下他的作用。Cygwin主要是用来处理不同平台间的转化工作,例如Android是基于Linux的框架集,而我们常使用的系统却是windows系统,所以使用它来将库文件从windows转为基于Linux系统的。当然,如果使用的系统是Linux的话则无需这个步骤了。

既然在这里介绍了它,无可置疑会用到它的。回到上面NDK环境的配置,怎么样验证环境变量是否配置成功那?答案就是使用这个Cygwin工具。我们打开它,在里面输入ndk-build,如果没有报错而是出现这个结果的话,则说明环境变量配置成功:

哦,这里的错误是因为没设定项目的路径,这里不用理会即可。

NDK的使用步骤:

实际上,NDK的使用流程与之前介绍的《Android本地接口JNI使用分析》使用流程及内容很多都很相似,在这里,我只介绍与之前不同的一些东西,下面即为NDK的开发流程:

1、创建Java本地方法类

2、编译Java本地方法生成C/C++头文件

3、编写实现上面的C/C++实现文件

4、编译生成动态运行库(.so)

5、运行应用程序

下面,根据上面的流程来介绍下NDK的使用及注意事项。我的项目目录:

运行的效果如:

每点击按钮打印LOG日志。

创建Java本地方法:

创建Java本地方法与之前文章是相同的,只不过这里的LOG内容为”HelloNdk!”而已,代码如下:

publicclassVerifyNdkJniMethod{

static{

System.loadLibrary("hello_ndk");

}

publicstaticnativeStringhelloNdk();

}

编译Java本地方法:

和之前的文章内容相同,都是使用Javah命令来编译生成的class文件,从而生成对应的C/C++头文件,我的头文件:

/*DONOTEDITTHISFILE-itismachinegenerated*/

#include<jni.h>

/*Headerforclasscom_demo_verifyndk_jni_ndk_VerifyNdkJniMethod*/

#ifndef_Included_com_demo_verifyndk_jni_ndk_VerifyNdkJniMethod

#define_Included_com_demo_verifyndk_jni_ndk_VerifyNdkJniMethod

#ifdef__cplusplus

extern"C"{

#endif

/*

*Class:com_demo_verifyndk_jni_ndk_VerifyNdkJniMethod

*Method:helloNdk

*Signature:()Ljava/lang/String;

*/

JNIEXPORTjstringJNICALLJava_com_demo_verifyndk_1jni_ndk_VerifyNdkJniMethod_helloNdk

(JNIEnv*,jclass);

#ifdef__cplusplus

}

#endif

#endif

同样的,与之前的头文件编写方式相同,我的实现文件如下:

#include<stdio.h>

#include"VerifyNdkJniMethod.h"

JNIEXPORTjstringJNICALLJava_com_demo_verifyndk_1jni_ndk_VerifyNdkJniMethod_helloNdk

(JNIEnv*env,jclassobj)

{

return(*env)->NewStringUTF(env,"HelloNdk!");

}

编译生成动态库文件(.so):

在这里,与我们之前介绍的略有不同,我们任然需要编写Android.mk文件,我的mk文件如下(在文章的最下面会介绍下mk文件):

#指定源文件的位置

LOCAL_PATH:=$(callmy-dir)

#初始化与Make相关的环境变量

include$(CLEAR_VARS)

#库编译相关信息包括库名称、源码等

LOCAL_MODULE:=hello_ndk

LOCAL_SRC_FILES:=VerifyNdkJniMethod.c

#生成共享库

include$(BUILD_SHARED_LIBRARY)

同样需要将头文件和实现文件及mk文件放在一起,只不过这里我们必须在项目的根目录下新建一个jni目录,cd到这个目录下,使用ndk-build或是$NDK/ndk-build来编译生成动态库文件。这与之前有些不同,之前我们使用的是$NDK/ndk-build来编译,是因为之前我们没有通过NDK的方式来实现,而是借助工具Cygwin来实现生成共享库文件的(这个是成立的);而现在,我们配置了NDK的环境变量可以使用$NDK/ndk-build或是ndk-build都可以进行编译生成,不同的是使用NDK及进行编译的话,我们必须cd到项目根目录下的jni下,上面的编译命令才会生效。原因是这样的,使用NDK编译的时候,NDK自身带有编译器系统,在编译的时候,编译系统会在当前的目录下查找AndroidManifest.xml文件,若文件存在,则将当前的目录看做为Android工程目录。然后再转到jni目录下,根据Android.mk进行NDK编译。

运行应用程序:

这个过程与之前的文章《Android本地接口JNI使用分析》基本相同,我的代码如下:

publicclassVerifyNdkJniActivityextendsActivity{

privatestaticStringTAG="VerifyNdkJniActivity";

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_verify_ndk_jni);

}

publicvoidhelloNdk(Viewv){

Stringresult=VerifyNdkJniMethod.helloNdk();

log(result);

}

privatevoidlog(Stringlog){

Log.d(TAG,log);

}

}

Android.mk文件说明:

实际上,Android.mk文件的帮助文件在<NDK_HOME>/docs/ANDROID_MK.html中(不过是英文的),下面就介绍下吧!

LOCAL_PATH:=$(param...):

这个变量是用来在开发树中查找源文件,必须在mk文件的最开始处定义,一般情况下,使用下面的这种的编写格式:

LOCAL_PATH:=$(callmy-dir)

其中的my-dir为一个宏函数,$(callmy-dir)就是用来返回一个宏函数的值,一般Android.mk文件与源文件在同一个目录下。

Include$(CLEAR_VARS):

用来初始化mk文件中LOCAL_XXX的变量,但是上面的LOCAL_PATH除外,因为Android系统会将LOCAL_XXX的变量当作全局变量,所以会先对其进行初始化。

LOCAL_MODULE:=XXX:

用来标记在mk文件中描述的每一个模块,也就是要生成的库的名称。这个名称必须唯一并且不能含有空格,编译系统会自动产生适当的前缀和后缀,比如:libhello_jni.so文件。

LOCAL_SRC_FILES:=XXX.c/.cpp:

用来将包含将要被编译进打包模块的各个资源文件。同时,这些源文件所在的位置为LOCAL_PATH所指定的目录。

Include$(BUILD_SHARED_LIBRARY):

用来使用LOCAL_PATH、LOCAL_SRC_FILES等的变量值,创建名称为lib$(LOCAL_MODULE).so的库文件。

到这里,关于NDK的一些基本的东西介绍完了,如果想要更灵活的使用NDK,那么可以参看NDK中自带的simples,仔细研究学习,其位置在:<NDK_HOME>\samples\

/**

*欢迎加入技术群:179914858

*如果有任何问题请在评论中进行讨论学习

*/

更多相关文章

  1. . Android內核Porting相關背景知識 转载
  2. Android(安卓)NDK安装及使用简介
  3. Android使用ttf字体库替代替图片
  4. Android资源管理器程序
  5. Android(安卓)Okhttp断点续传面试深入解析
  6. Android内核开发:系统启动速度优化
  7. 交叉编译-5:使用NDK和CMake在Linux上编译Android动态库
  8. Android录音并进行本地转码为MP3
  9. Android模拟器正确应用与安装方法

随机推荐

  1. 教你用php将二维码和文字结合到一个背景
  2. 两分钟带你了解PHP中的运算符
  3. 2021最常用的8个代码编辑器推荐
  4. PHP方法处理微信昵称特殊符号过滤
  5. 推荐给初学者必看的PHP书籍
  6. php上传图片无法显示的问题
  7. 详解php中整数判断的方法(附代码)
  8. php中的绘图技术详解
  9. PHP如何实现支付宝支付功能(图文详解)
  10. PHP 数组常用函数总结