一着饥、作用
第三方用 C++ 寫好了一些功能,我們要在 Java 代碼中調(diào)用它們惰赋。
二宰掉、概念
Android NDK開發(fā)掃盲及最新CMake的編譯使用
(1)CMake 基本語法規(guī)則
Android NDK 開發(fā):CMake 使用
(2)JNI 寫法
強(qiáng)推-Android NDK開發(fā):JNI實(shí)戰(zhàn)篇
JNI 調(diào)用 Java 對象的屬性、方法
Java 方法傳參給 JNI 函數(shù)
(3)C語言基礎(chǔ)
C語言基礎(chǔ)及指針①基礎(chǔ)語法
<>
表示引入的是系統(tǒng)頭文件赁濒," "
表示引入的是第三方頭文件轨奄。
(4)JNI 的兩種注冊方式
Android NDK開發(fā):JNI基礎(chǔ)篇-靜態(tài)注冊
Android NDK開發(fā):JNI實(shí)戰(zhàn)篇-動態(tài)注冊
(5)JNI 回調(diào)
Android JNI 篇 - JNI回調(diào)的三種方法(精華篇)
三、集成過程
0.第三方提供源代碼
c_test.h
和c_test.cpp
第三方提供給我們一個(gè)方法拒炎,返回一個(gè)字符串挪拟。
我們要把它集成進(jìn) AS 工程
1. 目錄結(jié)構(gòu)
(1)新建cpp
文件夾
第三方提供的.cpp
文件直接放在該目錄下
(2)include
文件夾
第三方給的.h
格式的頭文件都放在該目錄下
(3)CMakeLists.txt
位于module
根目錄下,先新建個(gè)空文件放在這里占位枝冀,具體怎么寫后面再說
2. Java 中編寫native
方法
(1)寫native
方法
新建一個(gè)類專門用于和 native 進(jìn)行交互
public class SDKUtil {
static {
System.loadLibrary("ndkdemo-lib");
}
// 單例
private static volatile SDKUtil instance;
private SDKUtil(){
}
public static SDKUtil getInstance() {
if (instance == null) {
synchronized (SDKUtil.class) {
if (instance == null) {
instance = new SDKUtil();
}
}
}
return instance;
}
// native 方法
public static native String stringFromCpp();
}
(2)javac
編譯該類
將目錄切換到sdk
(3)javah
導(dǎo)出 JNI 頭文件
將目錄切換到java
3. 編寫JNI
方法
在cpp
文件夾下新建一個(gè)cpp
文件,命名隨意耘子,但為了好維護(hù)果漾,我們把它和想要生成的so
庫的名稱起得一致。
#include <jni.h>
#include "cpp_test.h"
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_sdk_SDKUtil_stringFromCpp(
JNIEnv *env,
jclass type)
{
const char * cppStr = cppFunction();
return env->NewStringUTF(cppStr);
}
要加上extern "C"
4. CMakeList.txt
CMake將C++文件編譯為so庫谷誓,這些so庫后續(xù)會被gradle打入apk包中
(1)填寫CMake
文件
cmake_minimum_required(VERSION 3.4.1)
add_definitions(-D ANDROID_PLATFORM)
#設(shè)置生成的so動態(tài)庫最后輸出的路徑
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI})
#.h文件目錄
include_directories(
${CMAKE_SOURCE_DIR}/src/main/cpp/include #h文件目錄
)
#add_library(libaudio_device STATIC IMPORTED)
#link_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include/lib)
add_library( # Sets the name of the library.
ndkdemo-lib #c/cpp代碼將要編譯成為so庫的名稱绒障,java代碼加載庫文件要用這個(gè)名稱
SHARED #動態(tài)庫
#自己的JNI實(shí)現(xiàn)
src/main/cpp/ndkdemo-lib.cpp
#引入的第三方實(shí)現(xiàn)相關(guān)
src/main/cpp/cpp_test.cpp # cpp代碼文件路徑,如有多個(gè)需依次填寫
)
find_library( #調(diào)用系統(tǒng)庫
log-lib #打印用
log )
target_link_libraries( # Specifies the target library.
ndkdemo-lib
OpenSLES
${log-lib} )
add_definitions
add_library
定義好要生成的so
庫的名稱
(2)將工程切換到Android
視圖捍歪,進(jìn)行如下操作
之后build.gradle
會發(fā)生相應(yīng)變化户辱。
注意兩個(gè)externalNativeBuild {}
的配置
4. 開始調(diào)用
在MainActivity
中調(diào)用鸵钝,返回結(jié)果顯示在界面上
public class MainActivity extends AppCompatActivity {
private TextView mTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTv = findViewById(R.id.tv);
mTv.setText(SDKUtil.getInstance().stringFromCpp());
}
}
四、重點(diǎn)說明
1. 將第三方提供的靜態(tài)庫集成到項(xiàng)目
【NDK】Android Studio2.2+使用CMake依賴多個(gè)第三方庫
(1)將靜態(tài)庫放在jniLibs下
(2)CMake添加依賴的靜態(tài)庫
參考文獻(xiàn)
Android Stuido:在現(xiàn)有工程中添加C/C++代碼
關(guān)于在Android中使用CMake你所需要了解的一切(二)
關(guān)于在Android中使用CMake你所需要了解的一切(一)