Android Kotlin/C++開發(fā)

1、新建項目

androidStudio老版本慢睡,需要勾選包含Kotlin,C++

新版本AS

選擇native C++
kotlin語言
NDK編譯調試工具

項目結構對比:

a铡溪、添加C++的模塊漂辐,需要在其build.gradle文件中增加配置

增加配置

可以配置第三方so庫,其存放路徑默認src/main/jniLibs

第三方so庫存放目錄

可以生成特定cpu架構的so庫

abiFilters配置

另外棕硫,so庫生成髓涯,也可以使用ndk-build指令來處理,不過需要配置哈扮,Application.mk,Android.mk文件

b纬纪、cmake文件

cmake文件內容

cmake_minimum_required(VERSION 3.4.1)?用來設置在編譯本地庫時我們需要的最小的cmake版本,AndroidStudio自動生成灶泵,我們幾乎不需要自己管

add_library用來設置編譯生成的本地庫的名字為native-lib育八,SHARED表示編譯生成的是動態(tài)鏈接庫(這個概念前面已經提到過了),src/main/cpp/native-lib.cpp表示參與編譯的文件的路徑赦邻,這里面可以寫多個文件的路徑髓棋。

find_library是用來添加一些我們在編譯我們的本地庫的時候需要依賴的一些庫,由于cmake已經知道系統(tǒng)庫的路徑惶洲,所以我們這里只是指定使用log庫按声,然后給log庫起別名為log-lib便于我們后面引用,此處的log庫是我們后面調試時需要用來打log日志的庫恬吕,是NDK為我們提供的签则。

target_link_libraries是為了關聯(lián)我們自己的庫和一些第三方庫或者系統(tǒng)庫,這里把我們把自己的庫native-lib庫和log庫關聯(lián)起來铐料。

c渐裂、C++文件編寫

C++文件編寫

d、聲明和加載

聲明和加載

kotlin中使用external聲明钠惩,java使用native聲明柒凉;加載庫,使用System.loadLibrary()方法


2篓跛、NDK代碼編寫

2.1膝捞、java代碼調用原生代碼

自動生成的模板工程既是;首先聲明愧沟,然后靜態(tài)加載蔬咬,最后就可以像本地方法調用了

注意kotlin代碼生成native方法鲤遥,不能使用Alt+Enter自動創(chuàng)建,java可以林艘;所以最好盖奈,先用java聲明后,在把java文件轉化為kotlin文件北启;也可以自己手寫

2.1.1 對應數據類型

基本數據類型
引用類型

2.1.2卜朗、生成native方法

JNIEXPORT和JNICALL都是JNI的關鍵字,表示此函數是要被JNI調用的

extern "C":兩種用途咕村,C++代碼使用c文件场钉,引用c文件頭;c代碼使用c++的方法或者變量

java/kotlin聲明方法在native對應方法

[extern "C"]?JNIEXPORT 返回參數類型 方法名(JNIEnv *env, jobject instance[,?方法類型 方法參數] [, 參數類型 參數] ...)

? ? 返回參數類型懈涛,參數類型為java類型對應的jni類型

? ? 方法名:包名(.替換成_)+ _ + java方法名

? ? 方法的參數個數比java參數個數多了2個逛万;

? ? JNIEnv*指針,是一個指向線程-局部數據的指針批钠;提供各種函數實現虛擬機功能宇植。需要注意的是,env變量是線程線程相關的埋心,不可從一個線程傳遞env變量到另外一個線程指郁。

? ? jobject是java調用實例,如果是java中靜態(tài)方法拷呆,則這個參數變?yōu)閖class instance

那么在C++子線程中如何獲取JNIEnv指針呢闲坎?

首先在JNI回調方法JNI_OnLoad中緩存JavaVM指針

JNI_OnLoad方法

然后使用JavaVM的AttachCurrentThread方法,使當前線程附著在虛擬機茬斧,這樣就獲得了JNIEnv實例腰懂,不過使用完畢后,需要使用DetachCurrentThread釋放项秉,如下圖

線程相關JNIEnv

其實java/kotlin方法的動態(tài)注冊也是在JNI_OnLoad方法中執(zhí)行處理的

2.2 調用java/kotlin(也就是JNIEnv的使用)

簽名規(guī)則

另外方法簽名: (參數簽名)返回值簽名

2.2.1 訪問域

? ? a绣溜、如果不存在jclass對象,則使用GetObjectClass獲取

? ? b娄蔼、通過GetFieldID/GetStaticFieldID 獲取?jfieldID

域的名字和簽名

? ? c怖喻、 通過Get<Type>Field/GetStatic<Type>Field 獲取域值

2.2.2 調用方法

? ? a、如果不存在jclass對象岁诉,則使用GetObjectClass獲取

? ? b罢防、通過GetMethodID/GetStatiMethodID 獲取?jMethodID

方法名字和簽名

? ? c、 通過Call<Type>Method/CallStatic<Type>Method,來調用方法

2.3 JNIEnv的字符串操作

新建字符串NewStringUTF:有native 字符串轉換為java字符串

獲取字符串GetStringUTFChars:java字符粗轉化為native字符串

釋放native字符串ReleaseStringUTFChars唉侄;獲取后需要釋放,否則內存泄漏

2.4 JNIEnv的數組操作

創(chuàng)建數組New<Type>Array 創(chuàng)建某個類型的數組

訪問數組Get<Type>ArrayRegion: 把java數組內容copy到native數組內

提交數組Set<Type>ArrayRegion: 把native數組內容copy到java數組內

直接操作java數據內存Get<Type>ArrayElements: native數組和java數組指向相同內容野建;最后參數是指向副本属划,還是堆中固定地址恬叹;

需要釋放Release<Type>ArrayElements;釋放模式有0同眯,JNI_COMMIT绽昼、JNI_ABORT三種模式

0:內容復制回java數組內,并釋放原生數組

JNI_COMMIT: 內容復制回java數組內须蜗,并不釋放原生數組

JNI_ABORT:釋放原生數組硅确,并不把native數組改變應用到java數組里

2.5 JNIEnv的字符緩存區(qū)

NewDirectByteBuffer:native緩存變換為java緩存

GetDirectBufferAddress: java緩存變換為native緩存

GetDirectBufferCapacity:獲得java緩存區(qū)大小

2.6JNIEnv操作java對象在JNI中引用范圍

局部引用:大部分JNI函數返回局部引用,局部引用不能再后續(xù)調用中被緩存以及重用明肮;? 刪除方法:DeleteLocalRef

全局引用:如果沒有被原生代碼顯示釋放菱农,則后續(xù)可用;NewGlobalRef 生成一個全局引用柿估,刪除?DeleteGlobalRef

弱全局引用:如果沒有被原生代碼顯示釋放循未,則后續(xù)可用;與全局引用不同的是秫舌,不阻止?jié)撛诘睦厥眨?

? ? ?生成:?NewWeakGlobalRef的妖,檢驗弱全局引用仍然指向活動的類:IsSameObject,刪除:DeleteWeakGlobalRef

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末足陨,一起剝皮案震驚了整個濱河市嫂粟,隨后出現的幾起案子,更是在濱河造成了極大的恐慌墨缘,老刑警劉巖星虹,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異飒房,居然都是意外死亡搁凸,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門狠毯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來护糖,“玉大人,你說我怎么就攤上這事嚼松〉樟迹” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵献酗,是天一觀的道長寝受。 經常有香客問我,道長罕偎,這世上最難降的妖魔是什么很澄? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上甩苛,老公的妹妹穿的比我還像新娘蹂楣。我一直安慰自己,他們只是感情好讯蒲,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布痊土。 她就那樣靜靜地躺著,像睡著了一般墨林。 火紅的嫁衣襯著肌膚如雪赁酝。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天旭等,我揣著相機與錄音酌呆,去河邊找鬼。 笑死辆雾,一個胖子當著我的面吹牛肪笋,可吹牛的內容都是我干的。 我是一名探鬼主播度迂,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼藤乙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了惭墓?” 一聲冷哼從身側響起坛梁,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎腊凶,沒想到半個月后划咐,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡钧萍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年褐缠,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片风瘦。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡队魏,死狀恐怖,靈堂內的尸體忽然破棺而出万搔,到底是詐尸還是另有隱情胡桨,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布瞬雹,位于F島的核電站昧谊,受9級特大地震影響,放射性物質發(fā)生泄漏酗捌。R本人自食惡果不足惜呢诬,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一涌哲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧馅巷,春花似錦膛虫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽撩独。三九已至敞曹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間综膀,已是汗流浹背澳迫。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留剧劝,地道東北人橄登。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像讥此,于是被迫代替她去往敵國和親拢锹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353