NDK和JNI解析與應用

目前有很多的招聘公司,在招聘android程序工程師的時候,在應聘要求中明確的提出了要熟悉NDK開發,或者是瞭解JNI開發,甚至是精通NDK和JNI開發,很多小夥伴對JNI都有所耳聞,特別是研究過java虛擬機的同學,但是這種對jni的瞭解,並沒有使他們擁有精通jni的勇氣,反而使他們感覺jni很難,反而不想去學,產生了畏難的心理,對於一些沒有接觸過jni的同學來說呢,剛開始是報着必勝的心態去學習JN的,但是因爲一直學習的是java,一看現在jni還要牽涉到C語言,頓時感覺jni無比的高深,在心理上就首先投降了JNI。

JNI真的很難嗎?

android工程師必須要學習JNI嗎?

應該怎麼學習JNI?

接下來,我通我對jni的學習來闡述一下我的觀點:

首先:說一句,jni不簡單,但是作爲android工程師,我們沒有必要精通jni;

什麼是JNI(Java Native Interface)?

其實JNI就是java接口語言(不是等於沒說嗎???),那什麼又是java接口語言呢?說白了,就是我們的java程序調用C程序的一個過度,一個翻譯,在此有很多人有一個誤解,就是一直以爲jni是android的技術,其實這種想法是錯誤的,jni是java中的技術,例如當我們用java在windows上開發程序,用jin調用系統的C代碼是很經常的,我們的運行在windows上的JVM也是依靠JNI和windows來進行溝通的。

  什麼是NDK?

NDK是google爲方便Android開發者通過C/C++本地語言編寫應用的開發包,其中有很多工具,比如我們在windows環境上寫好C代碼,我們可以用其中的ndk-build把C代碼打包成.so文件(.so文件是運行在linux上的函數庫文件)。

解壓後的NDK文件目錄:

jni和ndk的具體概念我們已經瞭解了,接下來我們就來看看如何開發jni程序:

首先還有講解一下,C代碼在windows上和在linux上的一些不同

Windows:

C -> .O -> .exe    .dll(wendow下的函數庫)

Linux

C-> .O ->.elf      .so(Linux下的函數庫)  .a(linux下的靜態函數庫)

我們在android項目中,就是要把我們寫的c代碼打包成.so文件庫,供java調用


開發步驟:

一:在java代碼中創建一個native方法:

public native String helloWorldFromC();

二:android工程這中創建一個jni文件夾

三:在jni文件夾中寫c代碼,c代碼中要有include<jni.h>

c代碼中的方法名,應該是Java_加上全類名(把全類名的“.”變爲“_”)加上java native的方法名

方法名也可以不用手寫,當定義好javanative方法後,在控制檯輸入 javah [類的全類名],此時可以得到c語言實現java代碼的頭文件,把頭文件導入jni文件夾中,並且在實現的c代碼中導入該頭文件,方法名從頭文件中複製即可;


四:把c代碼打包成函數庫:在控制檯進入到工程目錄,然後ndk-build;

注意:在ndk-build之前,jni文件夾中還需要有一個Android.mk文件;

Android.mk:告訴編譯器如何把C代碼打包成函數庫,此文件也在jni文件夾


五:在java代碼中引入函數庫


注意:引入函數庫的時候,不要看見xxxx.so,就把前面的名字引入,而是寫自己在android.mk文件中定義的要打包的函數庫的名字,此時應該是hello;

六:java中調用方法

在此打印一個Toast:


最後目錄結構爲:


以上就是比較簡單但是非常全面的在android中開發jni的步驟。

接下來我們來看一下怎麼在java調用c代碼的時候,向其傳遞參數:

在此只貼出代碼,其原理都是一樣的,只是一些規則和細節,需要查閱相關資料:

java本地代碼:

C代碼:

注意:當我們傳遞java字符串時,在jni中,我們應該把java字符串轉換爲C代碼中的字符數組,用如下方法即可:

Sdk開發常見錯誤:

1.java Native 不能是private的;

2.Jni文件夾命名錯誤;

3.方法名稱寫錯(因爲比較長,所以要注意)

4.直接工程異常,沒有日誌打印,一般是c代碼運行錯誤;

5.Android.mk文件中不要用中文的回車和空格

6.引用別人的函數庫(.so文件),需要自己的含有native方法的包名和函數庫的方法名中的包名一致;


通過以上的講解,我再來回到在文章開頭提問的幾個問題:

JNI難嗎?

JNI本身並不簡單,只是根據自己所處的領域,和自己的實際情況來決定學習的深度,當然如果對這方面比較有興趣,多學習一些東西總是好的。

android工程師有必要學習JNI嗎?

在android開發中,比如加密,計算等一些問題,我們爲了提高效率或者安全方面的考慮,JNI確實是一個很好的選擇,但是在android開發中一個項目中並不會大量的使用,所以,我們學習的時候,沒有必要去鑽牛角尖。

應該怎麼學習JNI?

看文檔,看NDK中的頭文件。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章