Android Studio配置CMake開發(fā)NDK

1.eclipse中的Jni開發(fā)流程(一)
2.eclipse中的Jni開發(fā)流程(二)
3.Android Studio配置CMake開發(fā)NDK

1.在SDK Tools中勾選安裝CMake掂碱、LLDB透揣、NDK

Paste_Image.png

2.配置一些快捷方式

參數(shù)講解

    javah   用于生成頭文件
    Program:$JDKPath$/bin/javah
    Parameters:-d ../jni -jni $FileClass$
    Working directory:$SourcepathEntry$\..\java
    ndk-build   用于構(gòu)建so包
    注意:MAC/Linux用ndk-build胧瓜,沒有.cmd后綴
    Program:D:\adt\sdk\ndk-bundle\ndk-build.cmd
    Parameters:什么都不用填
    Working directory:$ModuleFileDir$\src\main
Paste_Image.png
Paste_Image.png

3.在工程的local.properties文件中配置NDK的目錄

sdk.dir=C\:\\Users\\yuxue\\AppData\\Local\\Android\\sdk
ndk.dir=C\:\\Users\\yuxue\\AppData\\Local\\Android\\sdk\\ndk-bundle
Paste_Image.png

也可以使用圖形界面危纫,單擊模塊選擇Open Moude Setting吧趣,選擇好NDK的路徑

Paste_Image.png

4.編譯時如果檢查NDK過時了可以在gradle.properties文件中增加“android.useDeprecatedNdk=true”使它可以使用過時的NDK

android.useDeprecatedNdk=true

5.創(chuàng)建CMakeLists.txt文件并放在模塊的的根目錄

# 設(shè)置構(gòu)建本地庫所需的最小版本的cbuild榴捡。
cmake_minimum_required(VERSION 3.4.1)
# 創(chuàng)建并命名一個庫,將其設(shè)置為靜態(tài)
#  或者共享验游,并提供其源代碼的相對路徑幢炸。
# 您可以定義多個庫泄隔,而cbuild為您構(gòu)建它們拒贱。
#  Gradle自動將共享庫與你的APK打包宛徊。
add_library( hello-lib  #設(shè)置庫的名稱。即SO文件的名稱逻澳,生產(chǎn)的so文件為“l(fā)ibhello-lib.so”,在加載的時候“System.loadLibrary("hello-lib");”
                SHARED  # 將庫設(shè)置為共享庫闸天。
                src/main/jni/hello.cpp    # 提供一個源文件的相對路徑
                src/main/jni/helloJni.cpp    # 提供同一個SO文件中的另一個源文件的相對路徑
              )
#搜索指定的預(yù)構(gòu)建庫,并將該路徑存儲為一個變量斜做。因為cbuild默認(rèn)包含了搜索路徑中的系統(tǒng)庫苞氮,所以您只需要指定您想要添加的公共NDK庫的名稱。cbuild在完成構(gòu)建之前驗證這個庫是否存在瓤逼。
find_library(log-lib  # 設(shè)置path變量的名稱笼吟。
              log   #  指定NDK庫的名稱 你想讓CMake來定位。
               )
#指定庫的庫應(yīng)該鏈接到你的目標(biāo)庫霸旗。您可以鏈接多個庫贷帮,比如在這個構(gòu)建腳本中定義的庫、預(yù)構(gòu)建的第三方庫或系統(tǒng)庫诱告。
target_link_libraries( hello-lib     #指定目標(biāo)庫中撵枢。與 add_library的庫名稱一定要相同
                       ${log-lib}    # 將目標(biāo)庫鏈接到日志庫包含在NDK。
                        )
#如果需要生產(chǎn)多個SO文件的話精居,寫法如下
add_library( natave-lib  #設(shè)置庫的名稱锄禽。另一個so文件的名稱
                SHARED  # 將庫設(shè)置為共享庫。
                src/main/jni/nataveJni.cpp    # 提供一個源文件的相對路徑
              )
target_link_libraries( natave-lib     #指定目標(biāo)庫中靴姿。與 add_library的庫名稱一定要相同
                       ${log-lib}    # 將目標(biāo)庫鏈接到日志庫包含在NDK沃但。
                        )     

6.在模塊的build.gradle文件中添加

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.0"
    defaultConfig {
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}
Paste_Image.png

7.編寫Java中的Native方法

    public native  String getStr();
    public native  String gethelloJniStr();

8.生成C的頭文件

Paste_Image.png

生成后

Paste_Image.png

9.編寫C函數(shù)

#include "stdio.h"
#include "jni.h"
#include "string"
extern  "C"
JNIEXPORT jstring JNICALL Java_com_ljp_learnandroidadvanced_MainActivity_getStr
        (JNIEnv *env,
jobject jobject1){
    return env->NewStringUTF("hello world from cpp");
}
Paste_Image.png

至此,這個項目就可以運行了

更多的學(xué)習(xí)

Paste_Image.png
(1) .externalNativeBuild文件夾:用于存放cmake編譯好的文件佛吓,包括支持的各種硬件等信息绽慈,有點類似于build.gradle文件明確Gradle如何編譯APP;
(2) cpp文件夾:存放C/C++代碼文件辈毯,native-lib.cpp文件默認(rèn)生成的坝疼;
(3) CMakeLists.txt:cmake腳本配置文件,cmake會根據(jù)該腳本文件中的指令去編譯相關(guān)的C/C++源文件谆沃,并將編譯后產(chǎn)物生成共享庫或靜態(tài)塊钝凶,然后Gradle將其打包到APK中。

CMakeLists.txt文件解析如下:

# 指定cmke版本  
cmake_minimum_required(VERSION3.4.1)  
# add_library()命令用于向CMake添加依賴源文件或庫  
# 指令需傳入三個參數(shù)(函數(shù)庫名稱、庫類型耕陷、依賴源文件相對路徑)  
add_library(  # 生成函數(shù)庫的名稱掂名,即libnative-lib.so或libnative-lib.a(lib和.so/.a默認(rèn)缺省)  
             native-lib  
             # 生成庫類型:動態(tài)庫為SHARED,靜態(tài)庫為STATIC  
             SHARED  
             # 依賴的c/cpp文件(相對路徑)  
             src/main/cpp/native-lib.cpp )  
# find_library()命令用于定位NDK中的庫  
# 需傳入兩個參數(shù)(path變量哟沫、ndk庫名稱)  
find_library(  # 設(shè)置path變量的名稱饺蔑,這里為NDK中的日志庫  
              log-lib  
                            #指定cmake查詢庫的名稱  
                            #即在ndk開發(fā)包中查詢liblog.so函數(shù)庫,將其路徑賦值給log-lib  
              log )  
#target_link_libraries()命令用于指定要關(guān)聯(lián)到的原生庫的庫  
target_link_libraries(# 指定目標(biāo)庫嗜诀,與上面指定的函數(shù)庫名一致  
                  native-lib  
                  # 鏈接的庫猾警,根據(jù)log-lib變量對應(yīng)liblog.so函數(shù)庫  
                  ${log-lib} )  
通過查看native-lib.cpp方法,stringFromJNI目的是向Java層返回一個字符串隆敢。如果要在native-lib.cpp文件中添加新的方法发皿,必須添加在extern"C" { } 中,或者在每個方法前加extern"C", 否則會報找不到方法拂蝎。如果源文件為C穴墅,則須將extern“C”部分去掉,因為extern "C"的作用就是告訴編譯器以C方式編譯温自。

JNI開發(fā)打印日志

#include <android/log.h>
#define LOG_TAG "System.out.c"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

LOG的使用
    LOGD("TAGD,a=%d,b=%d",a,b);
    LOGI("TAGI,a=%d,b=%d",a,b);
    LOGW("TAGW,a=%d,b=%d",a,b);
    LOGE("TAGE,a=%d,b=%d",a,b);
Paste_Image.png

Android系統(tǒng)目前支持的CPU架構(gòu)

ARMv5玄货,ARMv7 (從2010年起)
x86 (從2011年起)
MIPS (從2012年起)
ARMv8,MIPS64和x86_64 (從2014年起)
每一個CPU架構(gòu)對應(yīng)一個ABI
CPU架構(gòu)           ABI
ARMv5   --->    armeabi
ARMv7   --->    armeabi-v7a
x86     --->    x86
MIPS    --->    mips
ARMv8   --->    arm64-v8a
MIPS64  --->    mips64
x86_64  --->    x86_64
armeabi:默認(rèn)選項悼泌,將創(chuàng)建以基于ARM* v5TE 的設(shè)備為目標(biāo)的庫松捉。 具有這種目標(biāo)
的浮點運算使用軟件浮點運算。 使用此ABI(二進(jìn)制接口)創(chuàng)建的二進(jìn)制代碼將可以
在所有 ARM*設(shè)備上運行券躁。所以armeabi通用性很強(qiáng)惩坑。但是速度慢
armeabi-v7a:創(chuàng)建支持基于ARM* v7 的設(shè)備的庫,并將使用硬件FPU指令也拜。
armeabi-v7a是針對有浮點運算或高級擴(kuò)展功能的arm v7 cpu以舒。
mips:MIPS是世界上很流行的一種RISC處理器。MIPS的意思是“無內(nèi)部互鎖流水級
的微處理器”(Microprocessor without interlocked piped stages)慢哈,其機(jī)
制是盡量利用軟件辦法避免流水線中的數(shù)據(jù)相關(guān)問題蔓钟。
x86:支持基于硬件的浮點運算的IA-32 指令集。x86是可以兼容armeabi平臺運行
的卵贱,無論是armeabi-v7a還是armeabi滥沫,同時帶來的也是性能上的損耗,另外需要
指出的是键俱,打包出的x86的so兰绣,總會比armeabi平臺的體積更小。
總結(jié)
如果項目只包含了 armeabi编振,那么在所有Android設(shè)備都可以運行缀辩;
如果項目只包含了 armeabi-v7a,除armeabi架構(gòu)的設(shè)備外都可以運行; 
如果項目只包含了 x86臀玄,那么armeabi架構(gòu)和armeabi-v7a的Android設(shè)備是無法
運行的瓢阴;
如果同時包含了 armeabi,armeabi-v7a和x86健无,所有設(shè)備都可以運行荣恐,程序在運
行的時候去加載不同平臺對應(yīng)的so,這是較為完美的一種解決方案累贤,同時也會導(dǎo)致
包變大叠穆。

我的CSDN博客地址:http://blog.csdn.net/wo_ha/article/details/78131635

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市畦浓,隨后出現(xiàn)的幾起案子痹束,更是在濱河造成了極大的恐慌检疫,老刑警劉巖讶请,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異屎媳,居然都是意外死亡夺溢,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門烛谊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來风响,“玉大人,你說我怎么就攤上這事丹禀∽辞冢” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵双泪,是天一觀的道長持搜。 經(jīng)常有香客問我,道長焙矛,這世上最難降的妖魔是什么葫盼? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮村斟,結(jié)果婚禮上贫导,老公的妹妹穿的比我還像新娘。我一直安慰自己蟆盹,他們只是感情好孩灯,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著逾滥,像睡著了一般峰档。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天面哥,我揣著相機(jī)與錄音哎壳,去河邊找鬼。 笑死尚卫,一個胖子當(dāng)著我的面吹牛归榕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吱涉,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼刹泄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了怎爵?” 一聲冷哼從身側(cè)響起特石,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鳖链,沒想到半個月后姆蘸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡芙委,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年逞敷,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灌侣。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡推捐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出侧啼,到底是詐尸還是另有隱情牛柒,我是刑警寧澤霞扬,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布炸裆,位于F島的核電站屿储,受9級特大地震影響项玛,放射性物質(zhì)發(fā)生泄漏肉微。R本人自食惡果不足惜抱环,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一敬拓、第九天 我趴在偏房一處隱蔽的房頂上張望老速。 院中可真熱鬧协饲,春花似錦畏腕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至而线,卻和暖如春铭污,著一層夾襖步出監(jiān)牢的瞬間恋日,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工嘹狞, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留岂膳,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓磅网,卻偏偏與公主長得像谈截,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子涧偷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

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