NDK:Android Studio NDK開發(fā)環(huán)境

搞了幾天,查了很多資料,基本上能用了。
求關(guān)注,求點(diǎn)贊。轉(zhuǎn)載請(qǐng)注明出處:http://www.lxweimin.com/p/c0ec29da278b


Android Studio 2.2 開始NDK開發(fā)是使用CMake的方式,配置CMakeLists.txt
開發(fā)環(huán)境:
Android Studio 2.2 RC
WIN10 企業(yè)版64位
ubuntu14.04
NDK 12.1.2
CMake 3.4.2


NDK開發(fā)主要有以下幾種情況:

  • 自己寫C/C++文件來生成.so動(dòng)態(tài)庫供JAVA調(diào)用
  • JAVA直接調(diào)用編譯好的.so動(dòng)態(tài)庫
  • C/C++鏈接已經(jīng)編譯好的.so動(dòng)態(tài)庫

1. 自己寫C/C++文件來生成.so動(dòng)態(tài)庫供JAVA調(diào)用

這種情況其實(shí)很簡單,如圖,勾選 include C++ Support然后一路 next

新建工程

然后Finish即可


工程選項(xiàng)

下圖對(duì)工程目錄進(jìn)行了介紹,可以在大圖中看清楚這些信息。


工程目錄和JAVA文件

這里其實(shí)就是返回了一個(gè)字符串,可以講的地方就是函數(shù)的名字
函數(shù)的名字是java+包名+類名+方法名
這里一般都是自動(dòng)生成,不會(huì)自己去寫,可以把這個(gè)函數(shù)刪掉,然后在JAVA本地方法處按 Alt+Enter來自動(dòng)生成,也可以通過javah命令來生成,這里不細(xì)說了。


C++文件

CMakeLists.txt這個(gè)文件,我把注釋都刪掉了,方便截圖,如果大家想看注釋的話可以自己建一個(gè)工程看。這個(gè)文件是給CMake用的,至于怎么用,不用去管它,想研究的話可以找CMake的資料去研究,我們只要知道怎么寫就行了,其實(shí)只要知道一部分語法就可以滿足我們的正常需求了。

這里貢獻(xiàn)一個(gè)CMake的資料:Practice.pdf 密碼:xqvh
如果有時(shí)間的話把這篇資料看完是很好的。如果沒時(shí)間就看我這篇好了。

CMakeLists.txt文件

自己寫C/C++文件來生成.so動(dòng)態(tài)庫供JAVA調(diào)用這里基本上就OK了。
同步一下,然后編譯,運(yùn)行,一般都不會(huì)出問題,什么都還沒開始寫,如果這個(gè)時(shí)候出了問題,找找自己機(jī)器和軟件的原因。這里不截圖演示了
如果需要修改名稱,比如我們的C++文件叫 world.cpp 生成庫的名字叫 hello(系統(tǒng)會(huì)自動(dòng)生成libhello.so)可以修改如下圖,當(dāng)然,JAVA中加載的庫也在改為hello,

修改

擴(kuò)展,也就是一些蛋疼的需求

擴(kuò)展1:多文件編譯

這時(shí)提出一種需求:我一個(gè)工程不可能只有一個(gè)C/C++文件,怎么辦。
這時(shí)就要多文件編譯。
我們寫一個(gè)num.c和num.h文件里面只有一個(gè)函數(shù),代碼如下。
函數(shù)的作用就是,給傳入的int型數(shù)字加10000然后返回。

//num.c
#include "num.h"
int getNum(int num){
    return num + 10000;
}

//num.h
#ifndef NDK1_NUM_H
#define NDK1_NUM_H
int getNum(int num);
#endif //NDK1_NUM_H

該函數(shù)在jni的函數(shù)中調(diào)用,如下圖。


調(diào)用

CMakeLists.txt文件中的add_library需要修改

add_library

然后同步一下就可以編譯了。

然后就報(bào)錯(cuò)了。。。


報(bào)錯(cuò)

這個(gè)錯(cuò)誤是在執(zhí)行Cmake的時(shí)候出現(xiàn)的,看了半天看不懂到底哪里錯(cuò)了,總共就那么幾行代碼。這個(gè)地方我真的是蛋疼了很久,最后我都不知道我自己是怎么解決的,反正就是亂嘗試,一不小心就通過了。
有一次我把num.c改成num.cpp再編譯就又通過了。這就尷尬了,這是歧視啊,這不是看不起我們這些純C語言的程序員嗎。不過能通過就好。這時(shí)想到是C和C++的兼容問題,于是我又把num.cpp改成了num.c在num.h中添加了extern"C",如下代碼所示。再編譯也通過了,總算不痛了。

#ifndef NDK1_NUM_H
#define NDK1_NUM_H
#ifdef __cplusplus
extern"C"
#endif//__cplusplusint 
getNum(int num);
#endif //NDK1_NUM_H
運(yùn)行結(jié)果

打開工程目錄下
\app.externalNativeBuild\cmake\debug\obj
可以看到該目錄下是生成的.so文件
.externalNativeBuild這個(gè)文件夾下的東西也可以自己研究一下

擴(kuò)展2:生成指定平臺(tái)的.so動(dòng)態(tài)庫

這里默認(rèn)是生成了所有平臺(tái)的動(dòng)態(tài)庫
如果要指定動(dòng)態(tài)庫的平臺(tái)
則在如圖所示位置修改

修改動(dòng)態(tài)庫平臺(tái)

寫下來方便大家復(fù)制

abiFilters "armeabi-v7a" , "armeabi" ,"x86"

這里就不截圖了,知道即可


2. JAVA直接調(diào)用編譯好的.so動(dòng)態(tài)庫

接著上面的例子,我們的工程已經(jīng)編譯好了一個(gè).so動(dòng)態(tài)庫,直接拿過來用好了。
把\app.externalNativeBuild\cmake\debug\obj 這個(gè)目錄和里面的東西剪切到\app\libs里,這個(gè)目錄其實(shí)無所謂,是我們自己設(shè)置的。
把CMakeLists.txt里面所有東西注釋掉,這樣就不會(huì)生成新的.so動(dòng)態(tài)庫混淆掉
修改app目錄下build.gradle
添加紅色方框的這段話。

這段話我是找遍了百度,也找遍了谷歌,最后在google官方的demo里找到的。這個(gè)github是個(gè)好東西,里面有很多新版NDK的例子,我就是在這個(gè)里面找到解決方案的。尋找的過程也頗為痛苦,也幸虧當(dāng)年練就了一身找資料的本事,比如你給我?guī)讉€(gè)字母和數(shù)字的組合,我就能給你找到幾個(gè)G的資源。。額,扯遠(yuǎn)了。

同步一下,看到左邊有了jniLibs這個(gè)文件夾


build.gradle

編譯以后運(yùn)行,運(yùn)行正常

運(yùn)行結(jié)果

從這個(gè)例子里面可以看到,JAVA調(diào)用已經(jīng)第三方編譯好的.so動(dòng)態(tài)庫,核心就是下面這段話,這里寫出來,方便大家復(fù)制。

sourceSets {    
    main {        
    // let gradle pack the shared library into apk        
    jniLibs.srcDirs = ['../app/libs']    
    }
}

3. C/C++鏈接已經(jīng)編譯好的.so動(dòng)態(tài)庫

這里寫兩個(gè)示例

  • 在本工程內(nèi)部再生成一個(gè).so動(dòng)態(tài)庫,一起編譯。

  • 在linux的環(huán)境下通過NDK編譯好.so動(dòng)態(tài)庫,然后把.so動(dòng)態(tài)庫放入工程

    在本工程內(nèi)部再生成一個(gè).so動(dòng)態(tài)庫,一起編譯。

把libs目錄下的.so動(dòng)態(tài)庫刪掉
首先把CMakeLists.txt文件之前我們寫的注釋去掉
修改為如圖所示,注意到左邊的cpp文件夾下按庫分了兩個(gè)文件夾,真是人性化。


CmakeLists.txt

同步以后編譯一下,生成了libhello.so和libnum.so動(dòng)態(tài)庫。


生成動(dòng)態(tài)庫

運(yùn)行一下沒有問題,就不截圖了。

在linux的環(huán)境下通過NDK編譯好.so動(dòng)態(tài)庫,然后把.so動(dòng)態(tài)庫放入工程

我的linux是部署在阿里云上的,之前我已經(jīng)測(cè)試過了,所以很多東西已經(jīng)裝好,裝東西的過程就不演示了。要裝的東西有ndk,vim。
先裝好NDK:安裝和配置過程
vim就直接使用,假如沒有的話,系統(tǒng)應(yīng)該會(huì)提示怎么裝,指令是

  sudo apt-get install vim-gtk

關(guān)于VIM的操作這里就不介紹了,如果再一句一句的教就太啰嗦了。
我是用xshell來連接遠(yuǎn)程服務(wù)器的,這里用虛擬機(jī)也可以
如果會(huì)linux的話我寫的這些指令應(yīng)該能看懂,看不懂也沒關(guān)系,照著輸就行,意思就是在/home/relengxing/下建了個(gè)num的文件夾,并進(jìn)入該文件夾,這個(gè)其實(shí)隨便建,想在哪里在哪里。


xshell

然后在num文件夾內(nèi)再新建一個(gè)jni文件夾,并進(jìn)入


新建jni文件夾

啟動(dòng)文件傳輸,把我們之前寫的 num.c和num.h復(fù)制進(jìn)去,當(dāng)然也可以自己手碼一遍,我這里就直接CTRL+C,CTRL+V了


文件傳輸

ls一下,看到已經(jīng)復(fù)制進(jìn)去了


jni文件夾

在jni中再創(chuàng)建一個(gè)Android.mk文件寫法如下,同樣寫下來,方便復(fù)制。

  LOCAL_PATH := $(call my-dir)  
  include $(CLEAR_VARS)  
  LOCAL_MODULE    := num  
  LOCAL_SRC_FILES := num.c  
                                                                                                                                                                                                            
  include $(BUILD_SHARED_LIBRARY)  
 #include $(BUILD_EXECUTABLE)
Paste_Image.png

在jni目錄或者num目錄下執(zhí)行:
ndk-build APP_ABI=all //編譯所有平臺(tái)
ndk-build APP_ABI=armeabi-v7a //編譯arm
ndk-build APP_ABI=mips //編譯mips
生成的文件在num/libs下,不同平臺(tái)對(duì)應(yīng)不同的目錄。
如圖所示,生成了以下動(dòng)態(tài)庫


生成動(dòng)態(tài)庫

把libs文件夾復(fù)制到我們的windows系統(tǒng)上來,放到Android工程的libs目錄下,如圖所示

libs目錄

刪除上一次生成的obj下的庫文件,防止干擾
修改CMakeLists.txt文件,把第一個(gè)add_library刪掉,也就是生成num庫的那個(gè)刪掉,因?yàn)槲覀円呀?jīng)在linux下生成好了,直接就行了,不用再生成一個(gè),編譯以后報(bào)錯(cuò)!!又是看不懂的錯(cuò)誤,然后我又左摸索,右摸索,內(nèi)事不決問百度,外事不決問谷歌,X事不決問天涯。
最后修改如下圖,同步一下,編譯。

Paste_Image.png

關(guān)鍵幾行寫一個(gè),方便復(fù)制
CMAKE_SOURCE_DIR 和 ANDROID_ABI 是系統(tǒng)已經(jīng)定義好的
CMAKE_SOURCE_DIR 就是CMakeLists.txt的路徑,
ANDROID_ABI就是根據(jù)你的平臺(tái)來選擇
set就相當(dāng)于C語言的#define,用lib_DIR來代替后面的內(nèi)容,引用的時(shí)候要寫成${lib_DIR}
IMPORTED的意思猜想一下就是導(dǎo)入了的
set_target_properties這個(gè)沒有深入研究,大致意思是設(shè)置目標(biāo)的一些屬性來改變它們構(gòu)建的方式。這里照著修改就行了。

set(lib_DIR ${CMAKE_SOURCE_DIR}/libs)
add_library(num SHARED IMPORTED )
set_target_properties(num PROPERTIES IMPORTED_LOCATION
    ${lib_DIR}/${ANDROID_ABI}/libnum.so)

運(yùn)行結(jié)果如下圖。


Paste_Image.png

擴(kuò)展

比如,我的頭文件沒有放在cpp目錄,動(dòng)態(tài)庫沒有放在libs。
而是放在和app文件夾同級(jí)的number文件夾下,頭文件放在number/include/下,庫文件放在number/libs/{不同平臺(tái)}/下,就要這樣寫了
include_directories是設(shè)置頭文件路徑

  set(lib_DIR ${CMAKE_SOURCE_DIR}/../number)
  add_library(num SHARED IMPORTED )
  set_target_properties(num PROPERTIES IMPORTED_LOCATION
      ${lib_DIR}/libs/${ANDROID_ABI}/libnum.so)

  include_directories(${lib_DIR}/include)

至此Android Studio NDK開發(fā)環(huán)境這篇告一段落。
大致的使用情況都有介紹。
如果還有問題可以拿上面那個(gè)github研究一下
如果這篇文章有什么問題歡迎在評(píng)論指出。
求贊,求關(guān)注。歡迎轉(zhuǎn)載,請(qǐng)注明出處:http://www.lxweimin.com/p/c0ec29da278b

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,030評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,310評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,951評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,796評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,566評(píng)論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,055評(píng)論 1 322
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,142評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,303評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,799評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,683評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,899評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,409評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,135評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,520評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,757評(píng)論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,528評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,844評(píng)論 2 372

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