上一次用到NDK還是在2011年,我還記得那年接了個外包,需求是將一些指令通過C寫到SD卡上,那會用的還是cgwin編譯的,再加上自己又不會C/C++,弄起來特費(fèi)勁。
當(dāng)時還寫了篇文章Android調(diào)用jni全過程,方便以后操作。現(xiàn)在再看,寫的太簡單了。根本不能做參考。
于是硬著頭皮,重新來一遍。這次將整個過程記錄下來,好記性不如爛筆頭,下次再需要時就不操心了。
來不及解釋了,老司機(jī)要開車了:
- 首先google下吧,幾乎都是11年到13年的帖子,太老了,不太有參考性,要是還讓我用cgwin來編譯,那我要抓狂了。
- 記得去年的I/O大會,說是Studio添加了對NDK的支持。那還是去android官網(wǎng)看看吧。搜下ndk,找到一個ndk preview,嗯,一年過去了,還只是preview,需要studio 1.3+, gradle 2.5+, SdkManager中的ndk-bundle。如果這些還沒有,那先準(zhǔn)備下。
- ndk-bundle里的samples居然還是eclipse版本的,還好android提供了一套studio版的samples,github上有:https://github.com/googlesamples/android-ndk.git 下載下來直接打開,等gradle sync吧。這個過程相當(dāng)之慢。
- 先把官網(wǎng)的preview文檔看完。基本上是知道怎么做了吧。等待是漫長的,還是多google下,看看其他人碰到什么坑吧。
- 突然發(fā)現(xiàn)原來eclipse也能直接編譯的,ndk builder in eclipse那也試試吧。當(dāng)然還得給裝個CDT。按照文檔配置一下,用eclipse編譯也還是挺方便的。
- gradle終于sync完了。跑一遍沒什么問題。很好??梢蚤_車了。
- eclipse跟studio都差不多,區(qū)別不大,eclipse中的Android.mk和Application.mk改到studio中的build.gradle中配置。
-
如果直接用studio,那定義好native方法,ide會報錯,提示你該創(chuàng)建對應(yīng)的c方法。然后就自動幫你生成了。。真心方便。如果用eclipse,那你得先用jni生成.h文件,再自己寫.c或.cpp文件。ndk01.png
ndk02.png -
這個.h文件可以不要的,像studio直接就幫你創(chuàng)建了.c文件。jni這一步只是幫你將native聲明的方法轉(zhuǎn)換成c的方法,你可以理解為interface。一般來說,需要C/C++的地方,都不會太簡單,所以不大可能一個文件就搞定,所以,最好不要在轉(zhuǎn)換的那個c文件中寫具體實(shí)現(xiàn)。你可以把它當(dāng)作proxy,橋接你的java方法與C方法。ndk03.png
-
這次用的C++,編譯的時候碰到了不少坑,比如要額外的導(dǎo)入一些包。ndk04.png
這些都是我google別人的配置,至于為什么,其實(shí)我也搞不清楚。
- 最坑的還是jni的參數(shù)類型要轉(zhuǎn)成相應(yīng)的C/C++類型?;绢愋瓦€好。當(dāng)出現(xiàn)一個jcharArray轉(zhuǎn)C++的char*和char[],我整個人都是崩潰的。還有多維數(shù)組在jni看來都是jObjectArray,你得手動轉(zhuǎn)成多維數(shù)組再去調(diào)C++,比iOS要麻煩太多了。還好我機(jī)智,沒答應(yīng)去支持傳對象。
- 當(dāng)然中間出了很多小坑,因為溝通不當(dāng),兩邊都沒有提前定義好方法參數(shù),導(dǎo)致我一直要改jni方法,以及jni對象轉(zhuǎn)換。有些C++需要額外define引用,不然編譯不通過。還有什么std::,真是惡心。
就說這么多吧,我做的功能是通過GPS與Sensor數(shù)據(jù)來判斷車主駕駛習(xí)慣,比如急剎車,急加速,急轉(zhuǎn)彎。等等。手機(jī)能拿到的數(shù)據(jù)緯度比較少,判斷的還不是很準(zhǔn)確,而且GPS還經(jīng)常亂漂,我走路都能有9.1m/s,太夸張了。還需要再優(yōu)化。
還有以前的同事也在做ndk,他做的是相機(jī)取景的邊緣檢測,比如說拍一張名片,要把名片邊緣描出來??上€沒從坑里跳出來。等他跳出來了再看看他的小結(jié)吧。
其實(shí)我不會C/C++,我一直給自己灌輸?shù)氖牵瑳]搞不定的問題,只有搞不定的人。當(dāng)遇到你搞不定的問題時,別擔(dān)心,別到處求人會不會NDK,不然會進(jìn)入一個死胡同。
先分析業(yè)務(wù),羅列可能用到的技術(shù)點(diǎn),通過TODO偽代碼串聯(lián)起來,mock測試通過后,再對每個難點(diǎn)單點(diǎn)擊破,不會的去google,最最重要的是,API都有官方說明,不要隨便相信博客轉(zhuǎn)載的文章!(重要的事情說三遍)
相關(guān)參考:
android-JNI學(xué)習(xí)之java和c++相互調(diào)用



