Android Studio 3.6 編譯C生成.so文件(NDK學(xué)習(xí)新手篇)

一:前言

? ??近期在學(xué)習(xí)Android NDK,對于怎么使用Android Studio 將C++編譯打包成".so"文件比較好奇,于是就在網(wǎng)上查閱了相關(guān)資料,因?yàn)閯傞_始入門,所以還是花了一些時(shí)間,本文主要記錄相關(guān)操作,希望能幫助跟我一樣初學(xué)習(xí)的小伙伴。

二:使用Android studio兩種方案實(shí)現(xiàn)?

(1)Android Studio 3.6 自帶.so 打包生成

(2)ndk-build 編譯C生成.so文件

三:準(zhǔn)備階段:

? ? 1. 使用Android studio 下載好NDK和CMake

方案一:

? ? 1. 使用Android Studio 創(chuàng)建一個(gè)C++項(xiàng)目(next 默認(rèn)配置創(chuàng)建)

????2. 創(chuàng)建好C++項(xiàng)目可能會報(bào)錯(cuò),需要配置下NDK路徑,如下圖所示

????3. 創(chuàng)建好項(xiàng)目后,點(diǎn)擊 Build -> Make Project

????4. 編譯好項(xiàng)目后,可以在編譯好后的apk文件中查看到打包生成之后的“.so”文件。

????5. 創(chuàng)建C++項(xiàng)目后,會默認(rèn)生成兩個(gè)文件和相關(guān)默認(rèn)配置

????到此使用Android studio 自帶打包".so"文件結(jié)束,接下來主要細(xì)講下,手動(dòng)使用 ndk-build 打包 .so文件

方案二:

????1. 創(chuàng)建一個(gè)類并添加本地

public class NDKStudyTools{

? ? //創(chuàng)建一個(gè)native 方法

? ? public native static StringstringFromJIN();

}

????2. 點(diǎn)擊:Build -> make Project

????3. 構(gòu)建好后,buid 目錄下會生成NDKStudyTools.class 文件(不同as 版本對應(yīng)的詳細(xì)目錄會有不同,不過都在build 目錄下,找下就有)

????4. 創(chuàng)建C++ .h 頭文件

? ? ? ? (1)打開Android Studio ->?Terminal ,使用命令進(jìn)入到項(xiàng)目main目錄:cd app\src\main

????(2)使用命令創(chuàng)建 .h 的頭文件(如果提示“找不到 javah 命令”,需要配置下jdk的環(huán)境變量)

javah -d jni -classpath ...\classes? com.junker.study.c.yagain.NDKStudyTools.class

命令字段介紹:

javah:生成頭文件

-d jni:在當(dāng)前定位到的目錄下創(chuàng)建一個(gè) jni 文件夾

-classpath ...\classes 指定要生成頭文件的字節(jié)碼文件目錄,即生成的 com.junker.study.c.yagain.NDKStudyTools.class 字節(jié)碼目錄?

注意:這個(gè) classes 文件目錄可能太長,輸入麻煩,我們可以找到 debug 文件夾,右鍵 copy path,復(fù)制文件目錄即可

(3)回車之后,會在mian目錄下創(chuàng)建一個(gè)jni文件夾并生成一個(gè) "xxx.h"的頭文件(頭文件命名也是按照包名加字節(jié)碼名的規(guī)范,以下劃線連接)

5. 在jni目錄下創(chuàng)建一個(gè)?.c 文件并實(shí)現(xiàn)com_junker_study_c_yagain_NDKStudyTools.h 頭文件中的本地方法

? ? (1)copy? .h 文件中的native方法到 .c文件中,此時(shí)會有警告,alt+enter 解除警告。

(2)實(shí)現(xiàn)好之后,點(diǎn)擊右上角:sync now 同步下

6. jni 目錄下再次 創(chuàng)建 .mk 文件

????(1)創(chuàng)建?Android.mk 文件并添加配置(注意:不要在文件中添加注釋字符,使用?ndk-build 命令編譯時(shí)會報(bào)錯(cuò))。

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE:=app

LOCAL_SRC_FILES:=ndk_test.c

include $(BUILD_SHARED_LIBRARY)


參數(shù)說明:(注:以下不用拷貝到文件中,此處只做說明)

LOCAL_PATH := $(call my-dir):

? ? 設(shè)置工作目錄,它用于在開發(fā)tree中查找源文件。宏my-dir由Build System提供,會返回Android.mk文件所在的目錄

include $(CLEAR_VARS):

? ? CLEAR_VARS變量由Build System提供。指向一個(gè)指定的GNU Makefile,由它負(fù)責(zé)清理LOCAL_xxx類型文件,但不是清理LOCAL_PATH,所有的編譯控制文件由同一個(gè)GNU Make解析和執(zhí)行,其變量是全局的。所以清理后才能便面相互影響,這一操作必須有。

LOCAL_MODULE:=app:

? ? 模塊必須定義,以表示Android.mk中的每一個(gè)模塊,名字必須唯一且不包含空格,Build System會自動(dòng)添加適當(dāng)?shù)那熬Y和后綴。例如,demo,要生成動(dòng)態(tài)庫,則生成libdemo.so。但請注意:如果模塊名字被定義為libabd,則生成libabc.so。不再添加前綴。

LOCAL_SRC_FILES := ndk_test.c:

? ? 指定參與模塊編譯的C/C++源文件名。不必列出頭文件,build System會自動(dòng)幫我們找出依賴文件。缺省的C++源碼的擴(kuò)展名為.cpp。

include $(BUILD_SHARED_LIBRARY):

? ? BUILD_SHARED_LIBRARY是Build System提供的一個(gè)變量,指向一個(gè)GUN Makefile Script。它負(fù)責(zé)收集自從上次調(diào)用include $(CLEAR_VARS)后的所有LOCAL_xxxxinx。并決定編譯什么類型

? ? 1. BUILD_STATIC_LIBRARY:編譯為靜態(tài)庫

? ? 2. BUILD_SHARED_LIBRARY:編譯為動(dòng)態(tài)庫

? ? 3. BUILD_EXECUTABLE:編譯為Native C可執(zhí)行程序

? ? 4. BUILD_PREBUILT:該模塊已經(jīng)預(yù)先編譯

(2)創(chuàng)建 Application.mk 文件并添加配置(注意:不要在文件中添加注釋字符,使用?ndk-build 命令編譯時(shí)會報(bào)錯(cuò))。

APP_ABI := all


參數(shù)說明:(注:以下不用拷貝到文件中,此處只做說明)

APP_ABI := all

????默認(rèn)生成支持的多種類型.so

示例圖:

7.?生成so庫

(1)?使用 Terminal 命令進(jìn)入到項(xiàng)目jni目錄:cd app\src\main\jni

(2)使用?ndk-build 命令生成 so 庫( 如果提示沒有,需要配置下ndk的環(huán)境變量)

8、使用so庫

(1)為了能加載 app.so 庫,需要在主module下的 build.gradle 文件夾的 android 下添加如下代碼:

sourceSets{

? ? main() {

? ? ? ? jniLibs.srcDirs =['src/main/libs']

? ? ? ? jni.srcDirs =[] //disable automatic ndk-build call, which ignore our Android.mk

? ? }

}

(2)在 NDKStudyTools.java 中加載 so 庫(注:庫名稱不需要寫 libapp,只用寫 app,也就是去掉lib前綴)

public class NDKStudyTools{

? ? // 動(dòng)態(tài)導(dǎo)入 so 庫

? ? static {

? ? ? ? System.loadLibrary("app");

? ? }

? ? //創(chuàng)建一個(gè)native 方法

? ? public native static StringstringFromJIN();

}

(3)驗(yàn)證使用,跑一跑run

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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