Android下jni開發之ndk的使用(下載、配置、編譯遇到的問題)
一、簡介
JNI和NDK很多Android開發初學者沒有搞明白這個問題,JNI是Java呼叫Native機制,是Java語言自己的特性全稱為Java Native Interface,類似的還有微軟.Net Framework上的p/invoke,可以讓C#或Visual Basic.Net可以呼叫C/C++的API,所以說JNI和Android沒有關係,在PC上開發Java的應用,如果執行在Windows平臺使用JNI是是經常的,比如說讀寫Windows的登錄檔。而NDK是Google公司推出的幫助Android開發者通過C/C++本地語言編寫應用的開發包,包含了C/C++的標頭檔案、庫檔案、說明文件和示例程式碼,我們可以理解為Windows Platform SDK一樣,是純C/C++編寫的,但是Android並不支援純C/C++編寫的應用,同時NDK提供的庫和函式功能很有限,僅僅處理些演算法效率敏感的問題
簡單點說,用C語言生成一個庫檔案,在java中呼叫這個庫檔案的函式。JNI的過程比較複雜,生成.so需要大量操作,而NDK就是簡化了這個過程。
Java通過JNI機制和C/C++溝通的具體步驟
1、編寫包含native本地方法的java類
2、通過javah工具生成C/C++語言的標頭檔案
3、使用C/C++語言實現標頭檔案
4、使用交叉編譯工具對C/C++原生代碼進行編譯,最後通過連結生成*.so可執行的C/C++庫
5、實際執行Java程式碼去和本地的C/C++程式碼互相溝通
二 、NDK開發環境的搭建
1.下載安裝Android NDK
2.NDK環境配置 http://jingyan.baidu.com/article/ff42efa91906b8c19e220234.html
三、通過連結生成*.so可執行的C/C++庫
開啟cmd,進入jni目錄,執行ndk-build命令,如果ndk-build執行不了,回到上一條環境配置
四、執行ndk-build命令 遇到的問題
1.android.mk: *** missing separator (did you mean TAB instead of 8 spaces?)或者*** missing separator的解決辦法
http://blog.csdn.net/z13144099248m/article/details/41800747
這個錯誤是由於在編寫這個檔案的時候,行前面用的是空格,而不是tab,所以造成了操作符丟失的錯誤。
解決辦法是:把縮排的空格delete掉,然後按tab鍵用tab代替4個空格。
2、android.mk: ***commands commence before first target.的原因
http://blog.csdn.net/dahaibeibe/article/details/8162955
上一行換行符號 \ 後面有空格
本行前面的空白有非法字元
3.android.mk: *** missing separator missing separator的解決辦法
http://blog.csdn.net/sunnyfans/article/details/8807427
總而言之,這三問題都是操作符有問題,建議刪除行前行後的空格用Tab/回車代替,所有的空格都有可能有問題,所以如果是貼上過來的android.mk需要注意下格式等要求,其他的問題以後遇到i補充i
4.執行成功後,在android 6.0 會報java.lang.UnsatisfiedLinkError: No implementation found for intcom.gauss.speex.encode.Speex.open(int) (tried Java_com_gauss_speex_encode_Speex_open and Java_com_gauss_speex_encode_Speex_open__I)這個錯誤
http://blog.csdn.net/donglynn/article/details/25377067
問題顯然是沒有找到相應的本地函式。解決辦法也很簡單,就是Java程式碼,.h檔案和.cpp檔案中的宣告,肯定有一個不對應的。
我是由於包名com.gauss.speex.encode.和貼上過來的程式碼不一致,自己生成.h檔案和copy過來的.cpp檔案中方法名不一致導致的找不到相應的 本地函式,坑爹的是這麼明顯的錯編譯竟然不報錯
五、android實現jni的步驟
(對這個我開始一直很混亂,百度了資料看了還是混亂,第二次android下jni下使用speex終於清晰點了,以下是當時參考連結,混亂時再跟著走一 遍就ok)
speex演算法在android上的移植 http://blog.csdn.net/zkw12358/article/details/25339003
speex編解碼在android上實現 http://blog.csdn.net/xyz_lmn/article/details/8013490
android SDK使用cygwin編譯.so檔案 http://blog.csdn.net/zkw12358/article/details/24560499
Android移植live555之二:android平臺下jni的使用 http://blog.163.com/[email protected]/blog/static/69429295201398115116782/