JNI学习总结(基础篇)

基本概念

JNI

JNI(Java Native Interface),Java本地接口,是为方便java调用C或者C++等本地代码所封装的一层接口。由于Java的跨平台性导致本地交互能力不好,一些和操作系统相关的特性Java无法完成,于是Java提供了JNI专门用于和本地代码交互。
无论是 Linux,Windows 还是 Mac OS,或者一些汇编语言写的底层硬件驱动都是 C/C++ 写的。Java和C/C++不同 ,它不会直接编译成平台机器码,而是编译成虚拟机可以运行的Java字节码的.class文件,通过JIT(Just-In-Time)技术即时编译成本地机器码,所以有效率就比不上C/C++代码,JNI技术就解决了这一痛点,JNI 可以说是 C 语言和 Java 语言交流的适配器、中间件。其实主要是定义了一些JNI函数,让开发者可以通过调用这些函数实现Java代码调用C/C++的代码,C/C++的代码也可以调用Java的代码,这样就可以发挥各个语言的特点了。

NDK

NDK(Native Development Kit),是android提供的一个工具合集,帮助开发者快速开发C(或C++)的动态库,并能自动将.so和java应用一起打包成apk。NDK集成了交叉编译器(交叉编译器需要UNIX或LINUX系统环境),并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出.so。

NDK特点

ABI

ABI(Application binary interface)应用程序二进制接口。不同的CPU 与指令集的每种组合都有定义的 ABI (应用程序二进制接口),一段程序只有遵循这个接口规范才能在该 CPU 上运行,所以同样的程序代码为了兼容多个不同的CPU,需要为不同的 ABI 构建不同的库文件。当然对于CPU来说,不同的架构并不意味着一定互不兼容。

armeabi设备只兼容armeabi;
armeabi-v7a设备兼容armeabi-v7a、armeabi;
arm64-v8a设备兼容arm64-v8a、armeabi-v7a、armeabi;
X86设备兼容X86、armeabi;
X86_64设备兼容X86_64、X86、armeabi;
mips64设备兼容mips64、mips;
mips只兼容mips;

就目前市场份额而言,绝大部分的设备都已经是armeabi-v7a、arm64-v8a,可以考虑只保留armeabi-v7a架构的SO文件,这样能获得更好的性能效果。

开发流程

本文根据版本的不同介绍了两种在Android Studio中实现NDK的方法:Android Studio 2.2 以下和2.2以上。

Android Studio 2.2 以下版本

步骤如下

  1. 配置Android NDK环境
  2. 关联Andorid Studio项目 与NDK
  3. 创建本地代码文件(即需要在 Android项目中调用的本地代码文件)
  4. 创建Android.mk文件 & Application.mk文件
  5. 通过ndk-build命令编译上述文件,生成.so库文件,并放入到工程文件中
  6. 在Andoird Studio项目中使用NDK实现JNI功能

由于我学习的时候所使用的Android Studio版本已经是3.0了,所以这种方法已经失效了。编译时报错如下:

Error:Execution failed for task ':app:compileDebugNdk'.

> Error: Flag android.useDeprecatedNdk is no longer supported and will be removed in the next version of Android Studio.  Please switch to a supported build system.

  Consider using CMake or ndk-build integration. For more information, go to:

[https://d.android.com/r/studio-ui/add-native-code.html#ndkCompile](https://d.android.com/r/studio-ui/add-native-code.html#ndkCompile)

   To get started, you can use the sample ndk-build script the Android

   plugin generated for you at:

   C:\Users\peter\MyApp\JNIDemo\app\build\intermediates\ndk\debug\Android.mk

  Alternatively, you can use the experimental plugin:

[https://developer.android.com/r/tools/experimental-plugin.html](https://developer.android.com/r/tools/experimental-plugin.html)

  To continue using the deprecated NDK compile for another 60 days, set

  android.deprecatedNdkCompileLease=1519725194213 in gradle.properties

Android Studio 2.2 以上版本

只需要在Android Studio中的SDK tools中下载Cmake、NDK和LLDB三个工具,然后在Android Studio中新建项目的时候,在向导界面勾选C++支持选项然后创建项目就可以了。


勾选支持C++选项

项目创建好以后我们可以看到和普通Android项目有以下4个不同。

  • main 下面增加了 cpp 目录,即放置 c/c++ 代码的地方
  • module的 build.gradle 有修改
  • 增加了 CMakeLists.txt 文件
  • 多了一个 .externalNativeBuild 目录

项目目录

详细内容可以参看Android NDK开发扫盲及最新CMake的编译使用
由此可以总结出使用CMake编程的步骤如下:

  • 新建cpp目录,写好C/C++代码。
  • 创建并配置CMakeLists.txt文件。
  • build.gradle文件中根据情况进行配置,CMakeLists.txt文件的路径必须配置。
  • java代码中即可调用C/C++代码,运行程序。Java中调用JNI方法需要在具体的类中做以下操作:
//1、加载lib库
// Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

//2、声明调用的方法
/**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();

//3、调用方法
// Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());


小结

从一个小白的视角记录一下JNI编程需要掌握的基本概念以及自己跑个Hello world,做个学习笔记,感谢链接中作者的无私奉献。如果需要近一步学习可以参看JNI学习总结(实践篇)

参考文献

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,516评论 25 707
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,693评论 2 59
  • 本人为初学者,文章写得不好,如有错误,请大力怼我 或者看这里 如何使用jni进行开发 本文主要针对Android环...
    AlbertHumbert阅读 4,644评论 2 12
  • 前言 网上关于 Android 集成 FFmpeg 的文章很多,但大多数都只介绍了步骤,没有说明背后的原理,若之前...
    王英豪阅读 5,879评论 18 71
  • 国人似乎特别钟情吉尼斯纪录,不断的想要刷新,并且还自己独创了一系列的吉尼斯纪录。有千人蹲坑,万人打拳,最多人同时吃...
    亦铭阅读 281评论 0 0