Java培训教程ndk浅析_第1页
Java培训教程ndk浅析_第2页
Java培训教程ndk浅析_第3页
Java培训教程ndk浅析_第4页
Java培训教程ndk浅析_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

一、NDK产生的背景Android平台从诞生起,就已经支持C、C++开发。众所周知,Android的SDK基于Java实现,这意味着基于Android

SDK进行开发的第三方应用都必须使用Java语言。但这并不等同于“第三方应用只能使用Java”。在Android

SDK首次发布时,Google就宣称其虚拟机Dalvik支持JNI编程方式,也就是第三方应用完全可以通过JNI调用自己的C动态库,即在Android平台上,“Java+C”的编程方式是一直都可以实现的。不过,Google也表示,使用原生SDK编程相比Dalvik虚拟机也有一些劣势,Android

SDK文档里,找不到任何JNI方面的帮助。即使第三方应用开发者使用JNI完成了自己的C动态链接库(so)开发,但是so如何和应用程序一起打包成apk并发布?这里面也存在技术障碍。比如程序更加复杂,兼容性难以保障,无法访问FrameworkAPI,Debug难度更大等。开发者需要自行斟酌使用。于是NDK就应运而生了。NDK全称是Native

Development

Kit。NDK的发布,使“Java+C”的开发方式终于转正,成为官方支持的开发方式。NDK将是Android平台支持C开发的开端。二、为什么使用NDK1.代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。2.可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。3.提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。4.便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。三、NDK简介1.NDK是一系列工具的集合NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。2.NDK提供了一份稳定、功能有限的API头文件声明Google明确声明该API是稳定的,在后续所有版本中都稳定支持当前发布的API。从该版本的NDK中看出,这些API支持的功能非常有限,包含有:C标准库(libc)、标准数学库(libm)、压缩库(libz)、Log库(liblog)。四、使用NDK:Step:1.添加native接口注意写好native接口和System.loadLibrary()即可了,并无特别之处。P.S:onCreate()中对R.id.txt执行setText(),所以这里需要对xml布局文件按正常的开发步骤进行修改即可。新建Math.java,代码如下:publicclassMath{publicnativeStringgetStringFromNative();}MainActivity中调用此方法:publicclassMainActivityextendsActivity{

static{

System.loadLibrary("JniTest");//调用前需要load这个库

}

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

TextViewtxtView=(TextView)findViewById(R.id.txt);

txtView.setText(getStringFromNative());

}}Step:2.执行Build->MakeProject这一步骤执行一下,验证工程中并无其它错误,并对工程进行了编译,生成了.class文件..class文件的生成路径是在app_path/build/intermediates/classes/debug下的如果javah不是基于class文件生成c头文件,此步骤可不做,基于class文件生成c头文件和基于.java文件生成头文件是一样的Step:3.javah生成c头文件进入app_path/app/build/intermediates/classes/debug下,或app_path/app/src/main/java下执行:javahcom.zy.test.ndktest2.math生成.h文件两个生成的.h文件是一样的,生成任意一个即可,注意路径,不能到具体的包目录下,只能到debug或java路径下,然后指定的文件带包名在:app_path/app/src/main下新建一个jni文件夹,把.h拷贝到里面,.h文件只是为了得到c函数名,可以不拷贝到这里Step:4.编辑c文件在jni文件夹中新建math.c文件(可以是任意名字,只要函数名和.h中生成的函数名一样即可,也可以是.cpp文件),实现头文件中的方法,具体功能为直接return回一个String,并且使用android_log打印出相关日志。代码如下:/*

DO

NOT

EDIT

THIS

FILE

-

it

is

machine

generated

*/

#include

<jni.h>

#include

<android/log.h>

#ifndef

LOG_TAG

#define

LOG_TAG

"ANDROID_LAB"

#define

LOGE(...)

__android_log_print(ANDROID_LOG_ERROR,

LOG_TAG,

__VA_ARGS__)

#endif

/*

Header

for

class

lab_sodino_jnitest_MainActivity

*/

#ifndef

_Included_lab_sodino_jnitest_MainActivity

#define

_Included_lab_sodino_jnitest_MainActivity

#ifdef

__cplusplus

extern

"C"

{

//如果在c++中,就是cpp文件中,声明externc为了让c++兼容c语言的全局函数#endif

/*

*

Class:

lab_sodino_jnitest_MainActivity

*

Method:

getStringFromNative

*

Signature:

()Ljava/lang/String;

*/

JNIEXPORT

jstring

JNICALL

Java_com_zy_test_ndktest2_Math_getStringFromNative//此函数名跟.h中生成的函数名要一致

(JNIEnv

*

env,

jobject

jObj){

LOGE("log

string

from

ndk.");

return

(env)->NewStringUTF("Hello

From

JNI!");

}

#ifdef

__cplusplus

}

#endif

#endif

到这里后,我们再执行一个"Build->MakeProject",发现"MessagesGradleBuild"会给出提示如下:Error:Execution

failed

for

task

':app:compileDebugNdk'.

>

NDK

not

configured.

Download

the

NDK

from

/tools/sdk/ndk/.Then

add

ndk.dir=path/to/ndk

in

perties.

(On

Windows,

make

sure

you

escape

backslashes,

e.g.

C:\\ndk

rather

than

C:\ndk)

这里提示了NDK未配置,并且需要在工程中的perties文件中配置NDK路径。好了,提示很清楚了,那我们就进入下一步吧。注意:也可以不用javah生成.h文件,直接在native方法上按alt+enter在上面按alt+enter生成c层的方法这样如果没有jni文件夹和.c文件的情况下,会自动生成jni文件夹和跟.java类名一样的.c类,对应的方法会自动生成,如果已经存在jni和.c文件,在对应.java文件中添加一个新的natvie方法,自动生成时会自动找到对应的.c文件并生成新加native方法对应的c方法,如果要修改为.cpp,记得在全局方法上加externc声明Step:5.获取NDKas中在线获取:使用AndroidStudio内置的SDK管理器下载NDK。或者在项目上右键打开ProjectStructure,切到的SDKLocation页进行安装这个NDK安装好后其目录在SDK目录下的ndk-bundle目录下单独下载并配置:下载地址:/ndk/downloads/index.html#download下载完成后(mac版),获取.bin文件Mac解压.bin文件1.获取文件权限chmoda+xandroid-ndk-r10c-darwin-x86_64.bin2.解压出文件./android-ndk-r10c-darwin-x86_64.bin3.在这里配置路径:或配置perties:Step:6.配置NDK这一步包括两个动作:1.指明ndk路径2.修改build.gradle配置

工程中共有两个build.gradle配置文件,我们要修改的是在<Project>\app\build.gradle这个文件。为其在defaultConfig分支中增加上

以上配置代码指定的so库名称为JniTest,链接时使用到的库,对应android.mk文件中的LOCAL_LDLIBS,及最终输出指定三种abi体系结构下的so库。添加后如下图:3.在perties下加入android.useDeprecatedNdk=true这时,再执行"Build->RebuildProject",就可以编译出so文件了。但在Window平台上会出现一个问题:Error:Execution

failed

for

task

':app:compileDebugNdk'.

>

ernal.LoggedErrorException:

Failed

to

run

command:

D:\Mission\adt-bundle-windows\ndk-r10b\ndk-build.cmd

NDK_PROJECT_PATH=null

APP_BUILD_SCRIPT=C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\Android.mk

APP_PLATFORM=android-21

NDK_OUT=C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\obj

NDK_LIBS_OUT=C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\lib

APP_ABI=armeabi,armeabi-v7a,x86

Error

Code:

2

Output:

make.exe:

***

No

rule

to

make

target

`C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\obj/local/armeabi/objs/JniTest/C_\Users\sodinochen\AndroidstudioProjects\JniTest2\app\src\main\jni',

needed

by

`C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\obj/local/armeabi/objs/JniTest/C_\Users\sodinochen\AndroidstudioProjects\JniTest2\app\src\main\jni\main.o'.

Stop.

出现这个错误很莫名其妙..几番折腾下,找到一个视频出来了大概原因及解决方式:出处见Youtube视频02:50分开始:/watch?v=okLKfxfbz40#t=362在Windows下NDK一个bug,当仅仅编译一个文件时出现会出现此问题,解决方法就是再往jni文件夹加入一个空util.c文件即可。编译出来的库文件被Studio输出到了下图的路径中Step:7.安装运行界面:查看Log打印:Step:8.调试在运行模块中打开jni调试开关然后选择自动生成好的native模块进行断点调试调试日志打印(打印到logcat):首先要加入

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论