NDK 环境配置看这篇就够了!
JNI—Android Studio下的 NDK 环境配置
- JNI与NDK的理解
- JNI
- 什么是JNI呢?
- 为什么用JNI呢?
- 怎么学JNI呢?
- NDK
- 什么是NDK呢?
- 为什么用NDK呢?
- 怎么学NDK呢?
- JNI与NDK的开发准备
- JNI原生开发流程(Eclipse)
- 基本流程
- 详细流程
- 补充说明
- NDK集成开发流程(Eclipse)
- 基本流程
- 详细流程
- 补充说明
- 重要配置
- NDK集成开发流程(AS)
- 详细流程
JNI与NDK的理解
JNI是一种协议
NDK是用来开发JNI的谷歌工具包
JNI
什么是JNI呢?
- Andriod系统架构(理解)
- 相当于桥梁的作用
Java Native Interface: java本地开发接口
- 通过jni就可以让java与C/C++代码实现互调
为什么用JNI呢?
- native coder执行高效:大量的运算(极品飞车),万能解码(ffmpeg),Opengl(3D 渲染)
- 通过jni技术,可以扩展Android手机的功能-wifi热点等
- 代码的复用:ffmpeg,onencv(人脸识别库),7-zip
- 使用场景:考虑特殊情况(效率/操作硬件)
怎么学JNI呢?
- 学C语言-看懂代码
- 了解"JNI开发流程 "
NDK
编译C代码就需要用到NDK工具
什么是NDK呢?
- Native Develop Kits(本地开发工具包)
- Android提供的用来做JNI开发的工具包
为什么用NDK呢?
提高JNI开发的效率
- 生成代码
- 代码提示
- 多平台交叉编译
怎么学NDK呢?
了解"NDK"开发流程
JNI与NDK的开发准备
Android Studio下的 NDK 环境配置(两篇均可以)
https://blog.csdn.net/weixin_42814000/article/details/105259159
https://blog.csdn.net/weixin_42814000/article/details/105259289
Eclipse下的 NDK 环境配置
https://blog.csdn.net/weixin_42814000/article/details/105259122
JNI原生开发流程(Eclipse)
基本流程
- 在Java类中定义native方法
- 生成包含对应JNI函数声明的头文件
- 实现生成的JNI函数
- 借助NDK编译生成动态链接库文件(.so)
- 在Java类中加载动态连接库并调用native的方法
- 运行安装到ARM模拟器上
详细流程
在Java类中定义native方法
在Activity类中声明: public native String helloJNI();
生成包含对应JNI函数声明的头文件
1). 在命令行窗口中执行: javah Activity全类名(在src下执行)
说明有的电脑可能会提示GBK的不可映射字符: 添加 -encoding utf-82). 在src下会生成一个头文件: com_atguigu_hellojni_MainActivity.h
3). 头文件中包含一个native方法对应的JNI函数声明(需要后面实现):
JNIEXPORT jstring JNICALL Java_com_atguigu_hellojni_MainActivity_helloJNI(JNIEnv *, jobject)实现生成的JNI函数
1). 在应用下创建一个文件夹: jni
2). 将刚才生成的头文件复制到此文件夹下
3). 创建一个c文件来实现生成的JNI函数声明: test.c
#include "com_atguigu_hellojni_MainActivity.h"JNIEXPORT jstring JNICALL Java_com_atguigu_hellojni_MainActivity_helloJNI(JNIEnv * env, jobject jobj) {return (*env)->NewStringUTF(env, "Hello from C");}
借助NDK编译生成动态链接库文件(.so)
1). 解压NDK包, 配置NDK文件夹到path(不能包含空格)
2). 借助NDK下的文档(ANDROID-MK.html)编写用于编译的文件(jni/Android.mk)
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := hello-jni #指定生成的so文件的唯一标识LOCAL_SRC_FILES := test.c #指定包含JNI函数的c文件名include $(BUILD_SHARED_LIBRARY)
3). 在命令行窗口中进入应用根目录, 执行ndk-build命令, 生成so动态链接库文件
so文件路径: /libs/armeabi/libhello-jni.so
在Java类中加载动态连接库并调用native的方法
1). 在静态代码块中加载so文件:static {System.loadLibrary("hello-jni");}
2). 调用native方法:
String result = helloJNI();
- 运行安装到ARM模拟器上
补充说明
JNIEXPORT :
在Jni编程中所有本地语言实现Jni接口的方法前面都有一个"JNIEXPORT",这个可以看做是Jni的一个标志,至今为止没发现它有什么特殊的用处。
JNICALL :
这个可以理解为Jni 和Call两个部分,和起来的意思就是 Jni调用XXX(后面的XXX就是JAVA的方法名)。
NDK集成开发流程(Eclipse)
基本流程
- 安装配置NDK
- 将NDK关联到eclipse
- 为当前应用自动生成c文件和mk文件
- 定义naitve方法
- 实现native方法对应的JNI函数
- 一键编译生成so文件
- 加载动态库, 并调用native方法
- 运行应用安装到ARM模拟器上
详细流程
安装配置NDK
1). 解压NDK的zip包到非中文目录
2). 配置path : 解压后NDK的根目录----->ndk-build
将NDK关联到eclipse
Window–>Preferences–>Android–>NDK–>配置NDK的根目录
为当前应用自动生成c文件和mk文件
1). 选中当前应用右键–>Android Tools–>Add Native Support
2). 将生成的.cpp文件改为.c文件
3). 修改mk文件: 将.cpp改为.c
配置关联jni.h (见"配置关联jni.h文件"截图)
1). 选中当前应用右键–>Properties–>C/C++ General–>Paths and Symbols
2). 选择add–>选择File System–>选择文件夹android-ndk-r9\platforms\android-18\arch-arm\usr\include
3). 点击ok–>点击apply
定义naitve方法
public native String helloNDK();
实现native方法对应的JNI函数
1). 使用javah命令, 生成JNI头文件, 将其复制到jni文件下
2). 在c文件中实现h文件中的函数声明
3). 利用* 的NewStringUTF()函数, 返回字符串
一锤编译生成so文件
1). 使用工具栏中的"Build"工具点击锤子按钮生成
2). 文件路径: /libs/armeabi/libNDKTest.so
加载动态库, 并调用native方法
static {System.loadLibrary("NDKTest");}String result = helloNDK();
- 运行应用安装到ARM模拟器上
补充说明
修改C函数, 不需要再单独编译生成so文件, 可直接运行安装
APK只是将so打包了, 本质并不需要jni文件夹下的相关文件
多平台交叉编译
1、 arm
2、 intel
3、 mipsAndroid.mk详细介绍
#必须定义好LOCAL_PATH变量。它用于在开发树中查找源文件#宏函数’my-dir’,由编译系统提供,用于返回当前路径(包含c/c++文件)LOCAL_PATH := $(call my-dir)#清除除LOCAL_PATH之外的LOCAL_XXX变量#CLEAR_VARS由编译系统提供include $(CLEAR_VARS)#以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的#编译会产生的链接库文件(lib+名称+.so): libtest2-jni.soLOCAL_MODULE := test2-jni#指定将要编译打包进模块中的C或C++源代码文件#如果有多个, 以空格隔开LOCAL_SRC_FILES := test2.c#编译生成动态库(也就是.so文件)include $(BUILD_SHARED_LIBRARY)#编译生成静态库(也就是.a文件)#include $(BUILD_STATIC_LIBRARY)
重要配置
编写Android.mk
配置关联jni.h文件
编写Application.mk
NDK集成开发流程(AS)
详细流程
安装配置NDK
1).
https://github.com/inferjay/AndroidDevTools
根据自己的系统选择
2). 解压NDK的zip包到非中文目录
注意文件夹名字不能有空格
3). 配置Path环境变量 : 解压后NDK的根目录----->ndk-build
然后点击环境变量(建议配置在上面 用户变量,因为如果配置在系统变量的话,如果有一天你删除了系统变量的,那么会导致系统用不了,如果配置在用户变量,要进行删除时,如果用不了,只用重新创建一个用户就可以了,电脑还是可以使用。)
配置Path的原因就是可以通过cmd操作命令如果没有配置Path,不会弹出下面的信息,它会说命令没有被找到
给AS配置关联NDK
1). local.properties中添加配置
ndk.dir=G\:\\android-ndk-r10(=号后面为ndk的解压路径)
2). gradle.properties中添加配置
兼容老的ndk(老的版本):android.useDeprecatedNdk=true
android.useDeprecatedNdk=true
- 编写native方法:
public class JNIS {public native String helloJNI();}
定义对应的JNI
1). 在main下创建jni文件夹
2). 生成native方法对应的JNI函数声明头文件: 命令窗口中, 进入java文件夹
执行命令: javah com.atguigu.jnitests2.JNIS生成头文件: com_atguigu_jnitests2_JNIS.h函数声明: JNIEXPORT jstring JNICALL Java_com_atguigu_jnitests2_JNIS_helloJNI(JNIEnv *, jobject);
3). 将生成的头文件转移到jni文件夹下
4). 在jni下定义对应的函数文件: test.c
#include "com_atguigu_jnitests2_JNIS.h"JNIEXPORT jstring JNICALL Java_com_atguigu_jnitests2_JNIS_helloJNI(JNIEnv * env, jobject jobj) {return (*env)->NewStringUTF(env, "Hello from C");}
5). 在jni文件夹下创建一个空的C文件: empty.c
说明: 这是AS的bug, 必须至少2个C文件才能通过编译
指定编译的不同CPU
defaultConfig {ndk{moduleName "HelloJni" //so文件: lib+moduleName+.soabiFilters "armeabi", "armeabi-v7a", "x86" //cpu的类型}}
编译生成不同平台下的动态链接文件
1). 执行rebuild, 生成so文件
2). so文件目录: build\intermediates\ndk\debug\lib…
调用native方法:
1). 在native方法所在的类中加载so文件
static {System.loadLibrary("HelloJni");}
2). 在Activity中调用native方法:
String result = new JNIS().helloJNI();Log.e("TAG", "result="+result);
NDK 环境配置看这篇就够了!相关推荐
- macOS 上的 Charles 配置看一篇就够了
2021.11.9 更新,新增 iOS 模拟器抓取 Https 报文的配置方法. 文章目录 1. Charles 简介 2. Charles 工作原理 3. 组件介绍 4. macOS 代理设置 5. ...
- NDK撩妹三部曲(四)—NDK 开发如何优雅的定位 Native 异常,看这篇就够了
NDK 开发如何优雅的定位 Native 异常,看这篇就够了 从何说起? 摘要 案例实操 aaddr2line objdump ndk-stack 1.假设我们已经通过 adb logcat 拿到了程 ...
- React入门看这篇就够了
2019独角兽企业重金招聘Python工程师标准>>> 摘要: 很多值得了解的细节. 原文:React入门看这篇就够了 作者:Random Fundebug经授权转载,版权归原作者所 ...
- .NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了
本来这篇只是想简单介绍下ASP.NET Core MVC项目的(毕竟要照顾到很多新手朋友),但是转念一想不如来点猛的(考虑到急性子的朋友),让你通过本文的学习就能快速的入门ASP.NET Core.既 ...
- [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了
园子里关于ASP.NET Core Web API的教程很多,但大多都是使用EF+Mysql或者EF+MSSQL的文章.甚至关于ASP.NET Core Web API中使用Dapper+Mysql组 ...
- Spring Cloud入门,看这篇就够了!
点击▲关注 "中生代技术" 给公众号标星置顶 更多精彩 第一时间直达 概述 首先我给大家看一张图,如果大家对这张图有些地方不太理解的话,我希望你们看完我这篇文章会恍然大悟. 什 ...
- Docker入门实战看这篇就够了(最新详细以及踩过的坑)
Docker入门实战看这篇就够了 前言 初识 是什么 容器与虚拟机 能干什么 去哪玩 安装 先决条件 查看自己的内核 安装所需的软件包(支持devicemapper存储类型) 设置镜像的仓库 设置yu ...
- groovy if 判断字符串_Groovy快速入门看这篇就够了
原标题:Groovy快速入门看这篇就够了 来自:刘望舒(微信号:liuwangshuAndroid) 前言 在前面我们学习了和两篇文章,对Gradle也有了大概的了解,这篇文章我们接着来学习Groov ...
- [个人向]超快速了解微信小程序:看这篇就够了!(注册、语言、框架、配额等简要说明)
[个人向]超快速了解微信小程序看这篇就够了+相关简要说明 本文精炼微信小程序开发文档相关内容,旨在对初次接触并准备开发小程序的童鞋(比如自己)提供一个快速了解攻略.其中包括注册相关.语言.框架模式.相 ...
最新文章
- [原创]CentOS下Mysql双机互为备份
- 史上最受程序员待见的计算机入门读物——图解X系列
- R语言如何画个性化词云图
- python 读写utf8文件_Python关于 文件读写的总结
- vue项目将token存在(vuex)store和localstorage中
- html文档的文件头的主要作用是什么,文件头
- java中存在对多个对象加锁的情况_Java对象锁和类锁全面解析(多线程synchronized关键字)...
- [转载] java(三)对象的序列化与static、final关键字
- html阴影 渐变,CSS3:图层阴影及渐变
- mysql导出数据大概得多久_MySQL 导出数据
- 鼎立测试软件能锁网吗,路测软件鼎利通信Pioneer操作培训PPT(ET128).ppt
- PostmanCn: Postman中文版
- O2O模式成功案例分享 汲取精华化为己用
- android字体大小根据分辨率自动调整
- 强制双休!腾讯调整加班机制,21 点前必须离开工位
- es6根据对象属性获取到当前值的下标
- MySQL、PostgreSQL、NoSQL、CynosDB,究竟谁是数据库王者?
- Away3d粒子系统位置初始化
- 汇量科技蔡超:提高云使用率是云计算市场的下一个增长点
- 计算机人文素养教案,小学信息技术课堂中人文素养的教学探究
热门文章
- jupyter中更换工作目录最简单方式
- 003 matlab-反三角函数
- 彭罗斯阶梯(Penrose stairs
- 关于右下角广告弹窗的解决方案_小黄鸭
- 凌玮科技将在创业板上市:预计募资净额约8亿元,曾踩雷民生理财
- 泰森︱用拳击的眼光认识身体各部位的作用
- 完美解决Sqlite数据库版本过期解决方法
- Mrakdown学习
- java解析excel的js页面,JavaScript_通过Javascript读取本地Excel文件内容的代码示例,读取本地Excel文件内容的Javascri - phpStudy...
- 字符集和数据库的维护