Android Studio最新CMake使用教程(二): 生成共享庫.so文件并在其他項目中引用

在實(shí)際的Android開發(fā)中孵运,我們經(jīng)常要用到外部的動態(tài)鏈接庫.so文件,有時我們是使用別人編譯好的.so 文件,有時需要我們自己用NDK編譯出.so文件怕品,并且在另外的工程里使用。所以本文旨在編寫自己的Jni并且編譯生成特定的共享庫.so文件巾遭,然后在另外的工程里使用該共享鏈接庫肉康。
首先我們先創(chuàng)建一個Naive C++工程,具體創(chuàng)建方法見我上一篇博客灼舍。創(chuàng)建完成的目錄結(jié)構(gòu)大致如下:
?

image

這里為了在調(diào)用.so文件時方便區(qū)分開來吼和,我的工程名、包名以及共享庫名和庫源文件名都做了修改骑素。所以對應(yīng)的CMakeLists也做了修改:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
        testso-lib

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        testso-lib.cpp)

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
        testso-lib

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

在上篇博文里炫乓,我們知道初始創(chuàng)建的Native C++工程是在MainActivity調(diào)用Jni方法的,這里我們新建了一個接口類TestSoHelper献丑,并通過這個類調(diào)用Jni方法末捣。TestSoHelper的代碼如下:

package com.test.mytestsoproject;

public class TestSoHelper {
    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("testso-lib");
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public static native int intFromJNI(int a, int b);
}

對應(yīng)的Jni方法是:

extern "C"
JNIEXPORT jint JNICALL
Java_com_test_mytestsoproject_TestSoHelper_intFromJNI(JNIEnv *env, jclass instance, jint a,
                                                     jint b) {

    // TODO
    int returnValue = a + b;

    return returnValue;
}

這個Jni的方法十分簡單,方法傳入兩個整數(shù)创橄,然后返回這兩個數(shù)的和箩做。關(guān)于Jni的編寫,學(xué)過C語言的同學(xué)應(yīng)該一看就會了妥畏,基本是跟C/C++編寫一模一樣邦邦,在此不再贅述。

下面就是對應(yīng)的native方法的調(diào)用了醉蚁,我這里在MainActivity里簡單調(diào)用了一下燃辖,由于我們是為了編譯成.so文件,給其他工程用的网棍,所以在此不寫native方法的調(diào)用也是可以的黔龟。下面是我的調(diào)用:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Example of a call to a native method
    TextView tv = findViewById(R.id.sample_text);
    tv.setText(TestSoHelper.intFromJNI(1,2) + "");
}

}

基本是默認(rèn)的工程,只是把要顯示的文本改成了我Jni方法返回的數(shù)據(jù)。打包運(yùn)行的結(jié)果就是在手機(jī)上輸出數(shù)字1+2的和3捌锭。

然后我們把編寫好的Jni封裝成共享庫.so俘陷。只需要點(diǎn)擊Build [圖片上傳失敗...(image-883908-1583744056196)]

Make Project即可生成.so文件。生成的.so文件可以在下面的路徑下找到:app\build\intermediates\cmake\debug\obj观谦±埽可以看到工程生成了對應(yīng)不同android CPU架構(gòu)的.so文件:
?

image

?這樣我們就可以在別的工程里使用該.so 文件了。
這里我是直接用上篇博客創(chuàng)建的工程(MyTestProject)來引用這個共享庫.so文件的豁状,當(dāng)然捉偏,理論上這個共享庫可以被任意android工程引用。首先泻红,我們要把剛才生成的共享庫.so文件拷貝到我們要使用它的工程的libs文件夾下夭禽,最好是把不同CPU架構(gòu)的.so文件都拷貝進(jìn)去,這樣我們的應(yīng)用就能支持各種android系統(tǒng):
?

image

然后谊路,在build.gradle里添加以下代碼:
?

image
sourceSets.main {
    jniLibs.srcDirs = ['libs']
    jni.srcDirs = []
}

?
這是告訴工程要引用的共享庫所在的位置讹躯。接下來把剛才生成.so文件的工程里的Jni接口類TestSoHelper拷貝到我們當(dāng)前的工程里,注意缠劝,路徑也必須與原工程相同潮梯!另外,該類里的native方法可能會顯示為紅色惨恭,無法解析秉馏,這個不用去管,程序可以正常編譯運(yùn)行脱羡。
?

image

?到這里我們就可以直接在當(dāng)前工程(MyTestProject)里調(diào)用共享庫里的方法了萝究,簡單的調(diào)用如下:
?

image

?打包執(zhí)行下,結(jié)果果然與之前一樣锉罐!

以上方法是我個人使用Android Jni 的經(jīng)驗(yàn)帆竹,應(yīng)該是比網(wǎng)上其他引用自編寫共享庫的方法簡單很多,希望能幫助大家氓鄙。如有錯誤和不足馆揉,希望大家指正!

?您的贊賞是我堅持分享的最大動力 :)

?

?

?

?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抖拦,一起剝皮案震驚了整個濱河市升酣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌态罪,老刑警劉巖噩茄,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異复颈,居然都是意外死亡绩聘,警方通過查閱死者的電腦和手機(jī)沥割,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凿菩,“玉大人机杜,你說我怎么就攤上這事⌒乒龋” “怎么了椒拗?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長获黔。 經(jīng)常有香客問我蚀苛,道長,這世上最難降的妖魔是什么玷氏? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任堵未,我火速辦了婚禮,結(jié)果婚禮上盏触,老公的妹妹穿的比我還像新娘渗蟹。我一直安慰自己,他們只是感情好耻陕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布拙徽。 她就那樣靜靜地躺著刨沦,像睡著了一般诗宣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上想诅,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天召庞,我揣著相機(jī)與錄音,去河邊找鬼来破。 笑死篮灼,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的徘禁。 我是一名探鬼主播诅诱,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼送朱!你這毒婦竟也來了娘荡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤驶沼,失蹤者是張志新(化名)和其女友劉穎炮沐,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體回怜,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡大年,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翔试。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡轻要,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出垦缅,到底是詐尸還是另有隱情伦腐,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布失都,位于F島的核電站柏蘑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏粹庞。R本人自食惡果不足惜咳焚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望庞溜。 院中可真熱鬧革半,春花似錦、人聲如沸流码。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽漫试。三九已至六敬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間驾荣,已是汗流浹背外构。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留播掷,地道東北人审编。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像歧匈,于是被迫代替她去往敵國和親垒酬。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355

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