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

一:前言

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

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

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

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

三:準備階段:

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

方案一:

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

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

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

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

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

????到此使用Android studio 自帶打包".so"文件結束,接下來主要細講下,手動使用 ndk-build 打包 .so文件

方案二:

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

public class NDKStudyTools{

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

? ? public native static StringstringFromJIN();

}

????2. 點擊:Build -> make Project

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

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

? ? ? ? (1)打開Android Studio ->?Terminal ,使用命令進入到項目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:在當前定位到的目錄下創(chuàng)建一個 jni 文件夾

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

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

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

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

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

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

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

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

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):

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

include $(CLEAR_VARS):

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

LOCAL_MODULE:=app:

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

LOCAL_SRC_FILES := ndk_test.c:

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

include $(BUILD_SHARED_LIBRARY):

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

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

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

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

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

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

APP_ABI := all


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

APP_ABI := all

????默認生成支持的多種類型.so

示例圖:

7.?生成so庫

(1)?使用 Terminal 命令進入到項目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{

? ? // 動態(tài)導入 so 庫

? ? static {

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

? ? }

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

? ? public native static StringstringFromJIN();

}

(3)驗證使用,跑一跑run

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容