JNI學(xué)習(xí)總結(jié)(基礎(chǔ)篇)

基本概念

JNI

JNI(Java Native Interface)顾腊,Java本地接口斋扰,是為方便java調(diào)用C或者C++等本地代碼所封裝的一層接口谴仙。由于Java的跨平臺(tái)性導(dǎo)致本地交互能力不好陵刹,一些和操作系統(tǒng)相關(guān)的特性Java無(wú)法完成丈攒,于是Java提供了JNI專門(mén)用于和本地代碼交互。
無(wú)論是 Linux,Windows 還是 Mac OS巡验,或者一些匯編語(yǔ)言寫(xiě)的底層硬件驅(qū)動(dòng)都是 C/C++ 寫(xiě)的际插。Java和C/C++不同 ,它不會(huì)直接編譯成平臺(tái)機(jī)器碼显设,而是編譯成虛擬機(jī)可以運(yùn)行的Java字節(jié)碼的.class文件框弛,通過(guò)JIT(Just-In-Time)技術(shù)即時(shí)編譯成本地機(jī)器碼,所以有效率就比不上C/C++代碼捕捂,JNI技術(shù)就解決了這一痛點(diǎn)瑟枫,JNI 可以說(shuō)是 C 語(yǔ)言和 Java 語(yǔ)言交流的適配器、中間件指攒。其實(shí)主要是定義了一些JNI函數(shù)慷妙,讓開(kāi)發(fā)者可以通過(guò)調(diào)用這些函數(shù)實(shí)現(xiàn)Java代碼調(diào)用C/C++的代碼,C/C++的代碼也可以調(diào)用Java的代碼允悦,這樣就可以發(fā)揮各個(gè)語(yǔ)言的特點(diǎn)了膝擂。

NDK

NDK(Native Development Kit),是android提供的一個(gè)工具合集隙弛,幫助開(kāi)發(fā)者快速開(kāi)發(fā)C(或C++)的動(dòng)態(tài)庫(kù)架馋,并能自動(dòng)將.so和java應(yīng)用一起打包成apk。NDK集成了交叉編譯器(交叉編譯器需要UNIX或LINUX系統(tǒng)環(huán)境)全闷,并提供了相應(yīng)的mk文件隔離CPU叉寂、平臺(tái)、ABI等差異总珠,開(kāi)發(fā)人員只需要簡(jiǎn)單修改mk文件(指出“哪些文件需要編譯”屏鳍、“編譯特性要求”等),就可以創(chuàng)建出.so局服。

NDK特點(diǎn)

ABI

ABI(Application binary interface)應(yīng)用程序二進(jìn)制接口钓瞭。不同的CPU 與指令集的每種組合都有定義的 ABI (應(yīng)用程序二進(jìn)制接口),一段程序只有遵循這個(gè)接口規(guī)范才能在該 CPU 上運(yùn)行腌逢,所以同樣的程序代碼為了兼容多個(gè)不同的CPU,需要為不同的 ABI 構(gòu)建不同的庫(kù)文件超埋。當(dāng)然對(duì)于CPU來(lái)說(shuō)搏讶,不同的架構(gòu)并不意味著一定互不兼容。

armeabi設(shè)備只兼容armeabi霍殴;
armeabi-v7a設(shè)備兼容armeabi-v7a媒惕、armeabi;
arm64-v8a設(shè)備兼容arm64-v8a来庭、armeabi-v7a妒蔚、armeabi;
X86設(shè)備兼容X86、armeabi肴盏;
X86_64設(shè)備兼容X86_64科盛、X86、armeabi菜皂;
mips64設(shè)備兼容mips64贞绵、mips;
mips只兼容mips恍飘;

就目前市場(chǎng)份額而言榨崩,絕大部分的設(shè)備都已經(jīng)是armeabi-v7a、arm64-v8a章母,可以考慮只保留armeabi-v7a架構(gòu)的SO文件母蛛,這樣能獲得更好的性能效果。

開(kāi)發(fā)流程

本文根據(jù)版本的不同介紹了兩種在Android Studio中實(shí)現(xiàn)NDK的方法:Android Studio 2.2 以下和2.2以上乳怎。

Android Studio 2.2 以下版本

步驟如下

  1. 配置Android NDK環(huán)境
  2. 關(guān)聯(lián)Andorid Studio項(xiàng)目 與NDK
  3. 創(chuàng)建本地代碼文件(即需要在 Android項(xiàng)目中調(diào)用的本地代碼文件)
  4. 創(chuàng)建Android.mk文件 & Application.mk文件
  5. 通過(guò)ndk-build命令編譯上述文件彩郊,生成.so庫(kù)文件,并放入到工程文件中
  6. 在Andoird Studio項(xiàng)目中使用NDK實(shí)現(xiàn)JNI功能

由于我學(xué)習(xí)的時(shí)候所使用的Android Studio版本已經(jīng)是3.0了舞肆,所以這種方法已經(jīng)失效了焦辅。編譯時(shí)報(bào)錯(cuò)如下:

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三個(gè)工具椿胯,然后在Android Studio中新建項(xiàng)目的時(shí)候筷登,在向?qū)Ы缑婀催xC++支持選項(xiàng)然后創(chuàng)建項(xiàng)目就可以了。


勾選支持C++選項(xiàng)

項(xiàng)目創(chuàng)建好以后我們可以看到和普通Android項(xiàng)目有以下4個(gè)不同哩盲。

  • main 下面增加了 cpp 目錄前方,即放置 c/c++ 代碼的地方
  • module的 build.gradle 有修改
  • 增加了 CMakeLists.txt 文件
  • 多了一個(gè) .externalNativeBuild 目錄

項(xiàng)目目錄

詳細(xì)內(nèi)容可以參看Android NDK開(kāi)發(fā)掃盲及最新CMake的編譯使用
由此可以總結(jié)出使用CMake編程的步驟如下:

  • 新建cpp目錄廉油,寫(xiě)好C/C++代碼惠险。
  • 創(chuàng)建并配置CMakeLists.txt文件。
  • build.gradle文件中根據(jù)情況進(jìn)行配置抒线,CMakeLists.txt文件的路徑必須配置班巩。
  • java代碼中即可調(diào)用C/C++代碼,運(yùn)行程序嘶炭。Java中調(diào)用JNI方法需要在具體的類(lèi)中做以下操作:
//1抱慌、加載lib庫(kù)
// Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

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

//3眨猎、調(diào)用方法
// Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());


小結(jié)

從一個(gè)小白的視角記錄一下JNI編程需要掌握的基本概念以及自己跑個(gè)Hello world抑进,做個(gè)學(xué)習(xí)筆記,感謝鏈接中作者的無(wú)私奉獻(xiàn)睡陪。如果需要近一步學(xué)習(xí)可以參看JNI學(xué)習(xí)總結(jié)(實(shí)踐篇)寺渗。

參考文獻(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末信殊,一起剝皮案震驚了整個(gè)濱河市炬称,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鸡号,老刑警劉巖转砖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異鲸伴,居然都是意外死亡府蔗,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)汞窗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)姓赤,“玉大人,你說(shuō)我怎么就攤上這事仲吏〔幻” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵裹唆,是天一觀的道長(zhǎng)誓斥。 經(jīng)常有香客問(wèn)我,道長(zhǎng)许帐,這世上最難降的妖魔是什么劳坑? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮成畦,結(jié)果婚禮上距芬,老公的妹妹穿的比我還像新娘。我一直安慰自己循帐,他們只是感情好框仔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著拄养,像睡著了一般离斩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瘪匿,一...
    開(kāi)封第一講書(shū)人閱讀 51,146評(píng)論 1 297
  • 那天跛梗,我揣著相機(jī)與錄音,去河邊找鬼柿顶。 笑死茄袖,一個(gè)胖子當(dāng)著我的面吹牛操软,可吹牛的內(nèi)容都是我干的嘁锯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼家乘!你這毒婦竟也來(lái)了蝗羊?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤仁锯,失蹤者是張志新(化名)和其女友劉穎耀找,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體业崖,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡野芒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了双炕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狞悲。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖妇斤,靈堂內(nèi)的尸體忽然破棺而出摇锋,到底是詐尸還是另有隱情,我是刑警寧澤站超,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布荸恕,位于F島的核電站,受9級(jí)特大地震影響死相,放射性物質(zhì)發(fā)生泄漏融求。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一媳纬、第九天 我趴在偏房一處隱蔽的房頂上張望双肤。 院中可真熱鬧钮惠,春花似錦、人聲如沸素挽。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)缩赛。三九已至,卻和暖如春撰糠,著一層夾襖步出監(jiān)牢的瞬間酥馍,已是汗流浹背阅酪。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工汁针, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人砚尽。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓施无,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親必孤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,071評(píng)論 25 707
  • 用兩張圖告訴你兴想,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料赡勘? 從這篇文章中你...
    hw1212閱讀 12,712評(píng)論 2 59
  • 本人為初學(xué)者,文章寫(xiě)得不好狮含,如有錯(cuò)誤,請(qǐng)大力懟我 或者看這里 如何使用jni進(jìn)行開(kāi)發(fā) 本文主要針對(duì)Android環(huán)...
    AlbertHumbert閱讀 4,660評(píng)論 2 12
  • 前言 網(wǎng)上關(guān)于 Android 集成 FFmpeg 的文章很多几迄,但大多數(shù)都只介紹了步驟,沒(méi)有說(shuō)明背后的原理映胁,若之前...
    王英豪閱讀 5,902評(píng)論 18 71
  • 國(guó)人似乎特別鐘情吉尼斯紀(jì)錄,不斷的想要刷新脐瑰,并且還自己獨(dú)創(chuàng)了一系列的吉尼斯紀(jì)錄廷臼。有千人蹲坑苍在,萬(wàn)人打拳荠商,最多人同時(shí)吃...
    亦銘閱讀 290評(píng)論 0 0