最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Android Studio 4.0.+NDK .so庫生成打包

2023-05-12 18:05 作者:我夢見珍妮  | 我要投稿

JNI開發(fā)系列目錄

?

Android Studio 4.0.+NDK項目開發(fā)詳細教學

Android NDK與JNI的區(qū)別有何不同?

Android Studio 4.0.+NDK .so庫生成打包

Android JNI的深度進階學習

Android Studio 4.0.+NDK開發(fā) This files is not part of the project

目錄

?

前言

1. 什么是.so庫

2. cmake生成.so方案

1. 創(chuàng)建項目

2. 創(chuàng)建native函數(shù)

3. 測試JNI函數(shù)

4. 獲取.so文件

5. 生成多類型.so文件

6 .so文件測試

7. 小結(jié)

3. 傳統(tǒng)生成.so方案

1. 在Java類中聲明一個本地方法

2. 執(zhí)行指令javah獲得C聲明的.h文件

3. 獲得.c文件并實現(xiàn)本地方法

4. 創(chuàng)建Android.mk和Application.mk

5. 打包.so庫

6. 測試.so庫

4. external tools配置

1. javah配置

2. ndk-build配置

總結(jié)

?

總結(jié)

?

以Android studio 4.0.2來分析講解,gradle=6.1.1,如圖文和網(wǎng)上其他資料不一致,可能是別的資料版本較低而已

?

前言

涉及到一些算法或者底層驅(qū)動的時候,往往需要使用jni來開發(fā)。關(guān)于NDK和JNI如果還不了解,請查看我的另一篇博文《Android NDK與JNI的區(qū)別有何不同?》進行科普。

?

本篇博文主要是教學兩種.so庫的打包,穩(wěn)文中有詳細的圖文指導,跟著一步步操作就能學會.so文件的打包,對于NDK開發(fā)學習請閱讀我的《NDK開發(fā)系列》文章。

?

關(guān)于.so文件的生成有兩種方式可以提供給大家參考,一種是CMake自動生成法,另一種是傳統(tǒng)打包法。

?

1. 什么是.so庫

NDK為了方便使用,提供了一些腳本,使得更容易的編譯C/C++代碼,這個編譯文件為.so文件,它就C/C++庫,類似java庫.jar文件一樣。so是shared object的縮寫,見名思義就是共享的對象,機器可以直接運行的二進制代碼。大到操作系統(tǒng),小到一個專用軟件,都離不開.so,.so主要存在于Unix和Linux系統(tǒng)中。

?

在Android開發(fā)中它的生成是需要使用JNI將C/C++文件打包成so庫的,當然在其他開發(fā)軟件中,由其他工具將其打包成so庫。

?

.so文件在程序運行時就會加載,所以想使用Java調(diào)用.so文件,必有某個Java類運行時load了native庫,并通過JNI調(diào)用了它的方法。

?

2. cmake生成.so方案

使用該種方案生成.so文件,需要先創(chuàng)建一個支持Cmake的 C++ Project,如果不會創(chuàng)建項目請閱讀我的博文《Android Studio 4.0.+NDK項目開發(fā)詳細教學》

?

1. 創(chuàng)建項目

根據(jù)Android Studio 引導創(chuàng)建一個native C++ Project

?

2. 創(chuàng)建native函數(shù)

創(chuàng)建一個類,然后寫一個native 函數(shù),如:在這里插入圖片描述

?

?

鼠標懸空報紅的getData處,點擊Create JNI function。。。在這里插入圖片描述

?

在創(chuàng)建項目時,有自動生成一個native-lib.cpp文件,此時該文件中多了一個JNI getData函數(shù)在這里插入圖片描述

?

完善JNI getData函數(shù)在這里插入圖片描述

?

3. 測試JNI函數(shù)

public class MainActivity extends AppCompatActivity {

????static {

????????System.loadLibrary("native-lib");

????}

?

????@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(new MyNdkTest().getData());

????}

}

運行結(jié)果可見,JNI函數(shù)已被成功調(diào)用

?

在這里插入圖片描述

?

4. 獲取.so文件

將生成的.apk文件改為.zip文件,然后進行解壓縮,就能看到.so文件,默認支持x86_64在這里插入圖片描述

?

5. 生成多類型.so文件

默認生成的是x86_64,如果想支持多種庫架構(gòu),則可在app module的build.gradle中配置ndk支持。

?

android {

????.......

????defaultConfig {

????????...........

????????testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

????????externalNativeBuild {

????????????cmake {

????????????????cppFlags ""

????????????}

????????}

????????ndk {

????????????// 設(shè)置支持的 SO 庫構(gòu)架,注意這里要根據(jù)你的實際情況來設(shè)置

????????????abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'

????????}

????}

????externalNativeBuild {

????????cmake {

????????????path "src/main/cpp/CMakeLists.txt"

????????????version "3.6.0"

????????}

????}

}

?

6 .so文件測試

新建一個普通的Android程序,將庫放入程序中運行在這里插入圖片描述

?

1將生成的.so庫放入lib文件夾中

2之前生成.so文件函數(shù)的類,在調(diào)用程序中依然需要相同的包名、文件名及方法名

3可以將庫的加載放在java文件中,當程序啟動時會自動加載.so類庫

?

在這里插入圖片描述

?

7. 小結(jié)

在Android Studio自動創(chuàng)建的native C++項目默認支持CMake方式,它支持JNI函數(shù)調(diào)用的入口在build.gradle中。

?

在這里插入圖片描述

?

CMake的NDKx項目它有自己一套運行流程

?

1 Gradle 調(diào)用外部構(gòu)建腳本CMakeLists.txt

2 CMake 按照構(gòu)建腳本的命令將 C++ 源文件 native-lib.cpp 編譯到共享的對象庫中,并命名為 libnative-lib.so ,Gradle 隨后會將其打包到APK中

3 運行時,應(yīng)用的MainActivity 會使用System.loadLibrary()加載原生庫。應(yīng)用就是可以使用庫的原生函數(shù)getData()。

?OK,自動生成.so庫的方法就講到這了,Android Studio幫我們自動化做了很多東西,所以so easy。 下面講講傳統(tǒng)的.so庫生成方案。

?

3. 傳統(tǒng)生成.so方案

使用該種方案生成.so文件一定要先配置好NDK,如果不清楚如何配置NDK,請閱讀一篇關(guān)于配置NDK的博文《Android Studio 4.0.+NDK項目開發(fā)詳細教學》。其打包.so文件的基本流程如下所述

?

1. 在Java類中聲明一個本地方法

public class NDKTest {

????private native ?int ?count();

}

?

2. 執(zhí)行指令javah獲得C聲明的.h文件

在terminal中cd 到\app\src\main\java目錄下執(zhí)行如下指令:

terminal可能出現(xiàn)不能用,則使用cmd命令行

?

javah -encoding utf-8 -d ../jni -jni ?com.xuanyuan.ndktest.NdKTest

?

// ??javah:生成頭文件指令

// ??-encoding utf-8:編碼格式 utf-8

// ??-d ../jni:生成的文件放到與java目錄同級的jni文件中,jni文件若不存在會自動創(chuàng)建

// ?-jni:當前目錄下生成.h文件,當前目錄是cd進入的目錄,這里是\app\src\main\java

// ?com.xuanyuan.ndktest.NdKTest:包名+類名

指命令后會在…\app\src\main\jni目錄下生成一個com_xuanyuan_ndktest_NdKTest.h文件

?

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class com_xuanyuan_ndktest_NdKTest */

?

#ifndef _Included_com_xuanyuan_ndktest_NdKTest

#define _Included_com_xuanyuan_ndktest_NdKTest

#ifdef __cplusplus

extern "C" {

#endif

/*

?* Class: ????com_xuanyuan_ndktest_NdKTest

?* Method: ???test

?* Signature: ()Ljava/lang/String;

?*/

JNIEXPORT jstring JNICALL Java_com_xuanyuan_ndktest_NdKTest_test

??(JNIEnv *, jobject);

?

#ifdef __cplusplus

}

#endif

#endif

另一種方式是使用External tools工具,使用其javah指令,該指令需要我們自行配置,后面會單獨講解。

?

在這里插入圖片描述

?

3. 獲得.c文件并實現(xiàn)本地方法

生成的.h文件中函數(shù)相當于是一個抽象方法,具體實現(xiàn)需要我們來自定義。此時在jni中重建一個demo.c文件,將com_xuanyuan_ndktest_NdKTest.h中的完全復制過來,將函數(shù)完整實現(xiàn)。

自己實現(xiàn)的C++方法要寫對,不太熟悉C++的人找C++工程師支援,否則無法制作.so文件

?

在這里插入圖片描述

?

4. 創(chuàng)建Android.mk和Application.mk

在jni目錄中創(chuàng)建Android.mk和Application.mk兩文件,并配置其參數(shù),兩個文件如不編寫或編寫正常會出現(xiàn)報錯。

?

//Android.mk 參數(shù)

?

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

LOCAL_PATH := $(call my-dir)

?

//CLEAR_VARS變量由Build System提供。指向一個指定的GNU Makefile,由它負責清理LOCAL_xxx類型文件,但不是清理LOCAL_PATH

//所有的編譯控制文件由同一個GNU Make解析和執(zhí)行,其變量是全局的。所以清理后才能便面相互影響,這一操作必須有

include $(CLEAR_VARS)

?

// LOCAL_MODULE模塊必須定義,以表示Android.mk中的每一個模塊,名字必須唯一且不包含空格

//Build System 會自動添加適當?shù)那熬Y和后綴。例如,demo,要生成動態(tài)庫,則生成libdemo.so。但請注意:如果模塊名字被定義為libabd,則生成libabc.so。不再添加前綴。

LOCAL_MODULE := DEMO

?

?

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

LOCAL_SRC_FILES := demo.c

?

?

// 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)預先編譯

include $(BUILD_SHARED_LIBRARY)

?

**************************************************

#Application.mk 參數(shù)

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

APP_ABI := all

?

//APP_PLATFORM := android-16不配置,打包.so會出錯

APP_PLATFORM := android-16

如果我們需要進行多個C++文件一起編譯或者已有的.so參與編譯,這里給出配置示例

?

# Android.mk

????// 示例1:單個c++文件參與編譯

????include $(CLEAR_VARS)

????// 編譯出來的文件名

????LOCAL_MODULE := DEMO

????LOCAL_SRC_FILES := demo.c

?

????// 多個c++文件參與編譯

????include $(CLEAR_VARS)

????// 編譯出來的文件名

????LOCAL_MODULE := DEMO

????LOCAL_SRC_FILES := \

????????????test1.cpp \

??????????????test/ftest2.cpp \

???????????????test3.c \

?

// 示例2:.so文件參與模塊編譯

????include $(CLEAR_VARS)

?????// 編譯出來的文件名

????LOCAL_MODULE := DEMO2

????LOCAL_SRC_FILES := test/DEMO.so

????// 設(shè)置可被依賴

????include $(PREBUILT_SHARED_LIBRARY)

?

5. 打包.so庫

各種文件準備好后,cd到\app目錄下,執(zhí)行命令 ndk-build即可,我沒有用terminal,不知啥原因用不了。

執(zhí)行命令后會在libs文件夾中生成.so文件,默認支持4種命令庫。

?

?

同樣另一種方式是使用External tools工具,使用其ndk-build指令,該指令需要我們自行配置,后面會單獨講解。

?

在這里插入圖片描述

?

6. 測試.so庫

測試.so庫生成完畢,正??捎?。

?

在這里插入圖片描述

?

4. external tools配置

在上面制作.h文件和.so文件中要在cmd或者terminal中輸入javah、ndk-build命令比較麻煩,我們可以在external tools中進行配置,一次配置,終生幸福!

?

在這里插入圖片描述

?

1. javah配置

?

在這里插入圖片描述

?

//javah.exe的地址

Program:$JDKPath$\bin\javah

//生成.h文件的路徑指定在jni文件中,$FileClass$為源.java文件

Arguments:-encoding UTF-8 -d ../jni -jni $FileClass$

//進行編譯成.h文件的源.java文件目錄

Working directory:$ProjectFileDir$\app\src\main\java

?

2. ndk-build配置

?

在這里插入圖片描述

?

//ndk-build.cmd路徑

Program:$ModuleSdkPath$/ndk/21.3.6528147/ndk-build.cmd

//生成的.so文件存放位置

Arguments:NDK_LIBS_OUT=$ProjectFileDir$\app\libs

//編譯源文件的目錄

Working directory:$ProjectFileDir$\app\src\main

?

總結(jié)

本篇博文主要講解了兩種.so庫打包生成的方式,對于NDK開發(fā)的其他知識點學習請繼續(xù)閱讀我的系列文章。

?

在我們使用.so文件時,一定要記得做好配置,否則會出現(xiàn)無法找到.so庫的異常

?

android {

????compileSdkVersion 30

????buildToolsVersion "30.0.2"

????...

????sourceSets {

????????main {

????????????jniLibs.srcDirs = ['libs']

????????}

????}

}

?


Android Studio 4.0.+NDK .so庫生成打包的評論 (共 條)

分享到微博請遵守國家法律
肥乡县| 留坝县| 疏勒县| 赤壁市| 公主岭市| 石泉县| 荔波县| 安庆市| 洱源县| 全南县| 鄱阳县| 沈丘县| 酉阳| 堆龙德庆县| 深泽县| 天全县| 台东市| 长春市| 湖南省| 昆山市| 彩票| 宜良县| 黎平县| 罗江县| 焉耆| 榆树市| 卢湾区| 渭源县| 永德县| 萍乡市| 德昌县| 巩义市| 湖口县| 双城市| 民丰县| 浦城县| 新野县| 鄂托克前旗| 靖宇县| 招远市| 炎陵县|