NDK开发,其实是为了项目需要调用底层的一些C/C++的一些东西;另外就是为了效率更加高些。
主要优点:
1. 运行效率高;
2. 利于充分发挥软硬件优势;
3. 利于代码复用;
4. 降低版本控制成本;
5. 降低开发成本
主要缺点:
1. 开发难度相对高;
2. 调试难度相对高;
3. 增加开发团队规模;
C代码执行:
C代码被编译成库文件之后, 才能执行, 库文件分为动态库 和静态库 两种;
– 动态库 : unix环境下.so 后缀的是动态库, windows环境下.dll 后缀的是动态库; 动态库可以依赖静态库加载一些可执行的C代码;
– 静态库 :.a 后缀是静态库的扩展名;
库文件来源 :
C代码-进行-编译-链接操作之后, 才会生成库文件, 不同类型的CPU 操作系统 生成的库文件是不一样;
– CPU分类 : arm结构, 嵌入式设备处理器; x86结构, pc 服务器处理器; 不同的CPU指令集不同;
– 交叉编译 :windows x86编译出来的库文件可以在arm平台运行的代码;
– 交叉编译工具链 : Google提供的 NDK 就是交叉编译工具链, 可以在linux环境下编译出在arm平台下执行的二进制库文件;
• 配置ndk路径,在Project Structure中设置。
• 创建工程 声明native
方法
public class Uninstall {
static{
System.loadLibrary("uninstall");
}
public native void uninstall(String packageDir,int SDKVersion);
}
• 生成class
文件
执行Build-Make Project
命令,生成class
文件。所在目录为app_path/build/intermediates/classes/debug
• 执行javah
生成.h
文件
javah -help
用法:
javah [options]
其中, [options] 包括:
-o 输出文件 (只能使用 -d 或 -o 之一)
-d 输出目录
-v -verbose 启用详细输出
-h --help -? 输出此消息
-version 输出版本信息
-jni 生成 JNI 样式的标头文件 (默认值)
-force 始终写入输出文件
-classpath 从中加载类的路径
-cp 从中加载类的路径
-bootclasspath 从中加载引导类的路径
例如:javah -jni com.lingyongqian.xiaowenli.uninstall.Uninstall
生成.h
文件存放在app_path/build/intermediates/classes/debug
,将其剪切到main/jni
文件夹下。
目录结构如下:
• 在build.gradle
中配置ndk选项
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.lingyongqian.xiaowenli.testinstall"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
ndk {
moduleName "uninstall"
stl "stlport_static"
abiFilters "armeabi", "x86", "mips"
ldLibs "log"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
[注]这里可能会出现错误:解决方法就是在gradle.properties
文件中添加android:useDeprecatedNdk = true
就可以了
•执行Build
然后就可以在app/build/intermediates/ndk/debug/obj/local
下看到所有架构的so了
概念
Java本地接口(Java Native Interface), 它是一个协议, 该协议用来沟通Java代码和外部的本地C/C++代码, 通过该协议 Java代码可以调用外部的本地代码, 外部的C/C++ 代码可以调用Java代码;
C与Java如何交流 :
1. JNI规范 : C语言与Java语言交流需要一个适配器, 中间件, 即 JNI, JNI提供了一种规范;
2. C语言中调用Java方法 : 可以让我们在C代码中找到Java代码class中的方法, 并且调用该方法;
3. Java语言中调用C语言方法 : 同时也可以在Java代码中, 将一个C语言的方法映射到Java的某个方法上;
4. JNI桥梁作用 : JNI提供了一个桥梁, 打通了C语言和Java语言之间的障碍;
JNI中的一些概念:
native : Java语言中修饰本地方法的修饰符, 被该修饰符修饰的方法没有方法体;
Native方法 : 在Java语言中被native关键字修饰的方法是Native方法;
JNI层 : Java声明Native方法的部分;
JNI函数 : JNIEnv提供的函数, 这些函数在jni.h中进行定义;
JNI方法 : Native方法对应的JNI层实现的 C/C++方法, 即在jni目录中实现的那些C语言代码;
JNI在Android中作用
JNI可以调用本地代码库(即C/C++代码), 并通过Dalvik虚拟机与应用层和应用框架层进行交互,Android中JNI代码主要位于应用层和应用框架层;
应用层: 该层是由JNI开发,主要使用标准JNI编程模型;
应用框架层 : 使用的是Android中自定义的一套JNI编程模型,该自定义的JNI编程模型弥补了标准JNI编程模型的不足;
**[注]**NDK与JNI区别 :
NDK : NDK是Google开发的一套开发和编译工具集,主要用于Android的JNI开发;
JNI : JNI是一套编程接口,用来实现Java代码与本地的C/C++代码进行交互;