在做Android開發的過程中,經常會和底層的一些硬體打交道,Android的應用是在Java層開發的,底層的硬體功能是在通過HAL層來封裝的功能接口,如果要通過Java應用來和底層的HAL層交流,jni是必不可少的一個橋梁,jni可以打通Java到C++或者Java到C的通道。
由于最近需要封裝一層接口給底層調用,花了幾天時間來了解和調試了一下jni的小demo進行測試。
Jni的代碼可以通過Android.mk會編譯成so打包到apk中供應用來調用,正常的apk重命名為.zip檔案解壓後會看到有lib/armeabi的jni的 so目錄或者直接将jni 的so放到單闆的system/lib目錄來使用。
我這邊一直用的是Eclipse的ADT開發環境,沒有用Android studio,道理其實是一樣的。
具體步驟如下:
1、New 一個Android工程 ,名叫NDKTest;
2、下載下傳NDK開發工具,解壓并添加到Android的NDK配置路徑
可以翻牆的去Google官網,或者http://www.androiddevtools.cn/ 網站裡面 選擇Android SDK Tools中選擇NDK,可以選擇需要的版本,
由于我的win10是64 bit的,我這裡選擇下載下傳android-ndk-r13b-windows-x86_64.zip
下載下傳完成後,解壓到自己的Android開發目錄,不要有英語路徑,
點選Eclipse的Window-Preference-Android-NDK将NDK的解壓後的路徑添加進來
注意:有時候會無法添加,提示路徑無效
此時可以參考一些網友的經驗,在解壓後的ndk的路徑下建立一個空的ndk-build檔案
重新選擇Window-Preference-Android-NDK進入後發現可以正常添加
3、建立Test的Java類
A.添加需要加載的jni對應的so,此處so字元串不加lib字首和.so字尾。
拒說這樣最是為了款平台使用,因為jni好像也給windows使用,windows中的.dll檔案也會通過此種方法使用,具體自己可以去百度。
(此處的System.loadLibrary()不能寫錯,之前我第一次寫錯了寫成了System.load(),導緻錯誤使用了另外一種方法,一運作就報java.lang.UnsatisfiedLinkError: dlopen failed: library “NdkTest”無法找到庫錯誤)
B. 在此類中添加需要使用的native方法 getJniString();
4、自動生成jni檔案和編譯的Android.mk
選擇工程檔案,右擊-> Adnrdoid Tools->Android Native Support 輸入需要生成的jni的 so的名稱,
這裡我們命名和Test類中loadLibrary的so字元串名稱保持一緻。
生成的jni目錄中NdkTest.cpp隻有#include jni.h 一句話,Android.mk檔案正常。
Finish後會在此Android工程目錄下自動生成jni目錄,此目錄中包含了NdkTest.cpp檔案和Android.mk檔案。
5、接下來我們通過Test.java檔案自動生成jni的.h頭檔案
此Android工程編譯一下後會在
D:\Android\workspace\NdkTest\bin\classes\com\example\ndktest 目錄下自動生成Test.class檔案
在dos指令行用javah com.example.ndktest.Test生成
com_example_ndktest_Test.h頭檔案
(此處有坑
a.如果javah提示找不到,需要去添加一些Java的一些環境變量;
B.javah 後面跟的參數是jni的頭檔案命名格式,必須為Test的類的包名+類名,否則到時候運作時會提示方法找不到 ,特别感謝
http://blog.csdn.net/jiangwei0910410003/article/details/17465085文檔的幫助;
c.執行完成後會在src目錄下産生一個com_example_ndktest_Test.h的檔案,把此檔案拷貝到jni目錄下供後面使用,右擊F5重新整理可以顯示出來)
打開com_example_ndktest_Test.h檔案發現會報一些錯誤,提示一些關鍵字找不到,
此時需要在工程目錄,右擊->選擇Properties進行include一些頭檔案才行,例 如
在clean一下發現報錯消失。
6、來編寫NdkTest.cpp來進行com_example_ndktest_Test.h頭檔案函數的實作,這才是真正幹活的地方
a.為友善起見,需要把com_example_ndktest_Test.h 頭檔案include進來;
b.在com_example_ndktest_Test.h檔案中把jni函數的定義copy一份,複制到NdkTest.cpp
檔案中進行函數實作,這塊為了測試,隻寫一句話,傳回一個字元串供顯示。
7、jni的實作上面已經完成,下面直接在應用的主Activity中進行調用顯示。
8、clean一下工程,編譯後發現我們的jni 的so已經程式設計出來
運作此apk後發現正常
總結一下:
1、建立自定義Java類,此類中需要添加需要加載的jni 的so和native方 法;
2、自動生成jni檔案夾,包含.cpp和Android.mk檔案;
3、通過javah指令來生成自定義Java類對應jni的 .h頭檔案;
4、拷貝生成的jni的.h頭檔案到工程jni目錄中,在.cpp檔案中實作頭檔案中的方法;
5、上層應用通過調用自定義Java類中native方法來使用。
特别感謝:
1、windows下 ADT NDK開發環境配置
http://blog.csdn.net/danfengw/article/details/51844728
2、 Java中JNI的使用詳解第一篇:HelloWorld
http://blog.csdn.net/jiangwei0910410003/article/details/17465085
3、No implementation found for native 以及 java.lang.UnsatisfiedLinkError問題解決一例
http://blog.csdn.net/donglynn/article/details/25377067