32、JNI调用

1.1、NDK简介

1.1、NDK概述

NDK全称是Native Development Kit。NDK的发布,使“Java+C”的开发方式终于转正,成为官方支持的开发方式。NDK将是Android平台支持C开发的开端。

1、NDK优势

1.代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反编译难度较大。
2.可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。
3.提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。
4.便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。

2、NDK简介

1.NDK是一系列工具的集合
   NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。NDK集成了交叉编译器,

并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。

2.NDK提供了一份稳定、功能有限的API头文件声明
  Google明确声明该API是稳定的,在后续所有版本中都稳定支持当前发布的API。从该版本的NDK中看出,这些API支持的功能非常有限,包含有:

C标准库(libc)、标准数学库(libm)、压缩库(libz)、   Log库(liblog)。

3、NDK目录结构

build:该目录存放的使用NDK的mk脚本,mk脚本指定了编译参数
docs:该目录存放的是NDK的使用帮助文档
platforms:这里面存放的是与各个Android版本相关的平台(x86,arm,mips)相关C语言库和头文件
prebuilt:预编译工作目录
samples:存放的是演示程序
sources:存放的是NDK工具链的C语言源码
tests:测试相关的文件
toolchains:工具链,存放了三种架构的静态库等文件
ndk-build.cmd:Window平台使用NDK的命令
ndk-build:Linux平台使用NDK的命令

1.2、Jni入门

1.windows->preferences->Android->NDK(输入ndk路径),再确定。

427130d1-7488-4a88-9017-41fb4019a0b7

2.创建Android工程JNI入门,右键工程,找到Android Tools->点击add native support输入动态库名再确定。

a49b3f93-ceef-467b-a17c-83d78f761b30

3.此时,工程目录会出现jni文件夹,中间包含两个文件,并且我们还需要一些用到的头文件jni.h等。

313da0e5-0a71-4337-9549-c39dd2a8346f

4.导入头文件有两种方式:

a)进入NDK的目录,找到:D:\android-ndk-r10d\platforms\android-21\arch-arm\usr\include,下面有很多头文件,直接拷贝到eclipse的jni文件夹下即可。

b)直接配置导入所有的头文件,右键工程->properties->C/C++ General->Paths and Symbols->add->输入路径

f494a313-a8ac-430f-8052-6ba9f63e6931

总结:NDK版本下有三种不同的架构:

f77a1efe-94be-475a-b346-90316a753621

5.在MainActivity中定义native方法

433e0c1e-f90d-4fe2-ae76-b68dba0ce189

6.在hello.cpp或hello.c等源文件下输入如下代码,其中的语法便不叙述

03be4c2b-3af0-46c6-b4fe-b3c1eca2caa4

7.C代码中的命名规则(叙)

这里的命名规则指用于跟java文件中native方法对应的C语言方法,而C语言中的其他方法命名只要符合C语言规则就行。
jstring Java_com_itheima_jnihello_MainActivity_helloC(JNIEnv* env, jobject obj) 中,jstring是方法返回值类型,我们可以把jstring看成是java中String跟

C语言中char*类型的一个中间转换类型,java跟C语言的数据类型是不一样的,他们之间要想互相调用就必须通过一种中介来实现,这个中介就是在jni.h头文件中定义的。

关于更多的转换类型,在本文档的第2章会有更详细的说明。方法名第一个字母必须是Java,首单词大写,然后下划线_,然后是将该方法所在的包、类、方法用“_”连接起来,

比如com.itheima.jnihello.MainActivity类中的helloC方法,转变成C语言中的方法名为Java_com_itheima_jnihello_MainActivity_helloC。方法的形参有两个是必须的也就是

不管java中的方法是否有形参,但是C语言中对应的方法必须有JNIEnv* env,和jobject obj,如果java方法中还用其他形参,那么在C语言中严格按照顺序排在jobject obj参数

的后面即可。上面的env代表指向JVM的指针,obj是调用该方法的java对象。

8.首先查看NDK命令是否设置了环境变量,未设置则在Path中加入:D:\android-ndk-r10d

2f01efa8-784e-4b6b-9894-cc396c02c137

9.我们需要在工程中的jni目录中添加Android.mk配置文件。

8a89a679-a379-4fbf-9668-d4f654af6e1c

10.在cmd中,将当前目录切换到hello.c所在目录,然后重新执行ndk-build.cmd命令,这次成功编译

489add4a-fb43-4867-9194-a6ff0df45c29

11.发现在libs目录中多了两个文件夹armeabi和x86,这两个文件夹下分别包含了一个libhello.so动态链接库。这也代表着当前工程中的动态库支持arm架构和x86架构的cpu。

31480fea-2bb8-4790-b6b5-2c9cb1a62e24

12.可能你的并没有同时生成这两个文件,是因为我的工程中引入了Application.mk文件,因此你需要在jni文件夹下引入该文件。

6dcb7048-6916-45fd-a142-210c8840a2be

注:该清单其实只有一行内容,第一行是注释。APP_ABI参数指定要生成的目标文件支持的平台都有哪些,默认是armeabi如果想支持多个平台只需要空一格然后写出其他平台名字即可。

13.在MainActivity中调用C或C++语言

3c0cff67-19ae-44b2-a8ba-eca49e39124e

14.每次运行工程就会编译一次so文件,如果我们调用了外部so库的时候,编译时会自动删除外部so库。解决方法可以配置预编译或修改配置文件

1.百度搜索:android ndk如何取消"add native support" http://jingyan.baidu.com/article/380abd0a7309181d91192c55.html

2.配置预编译文件

libappsign.so has text relocations. This is wasting memory and is a security risk. Please fix.

翻译是:这个so库存在文字搬迁,这是一种消耗内存的操作,请修复。

导致这个问题产生的原因是因为使用了低版本的NDK编译的so文件导致的,是NDK中的一个bug。(目前找不到合理的解释)

转载于:https://www.cnblogs.com/pengjingya/p/5510134.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值