Android Studio加載NDK編寫的第三方SO

**

1.Linux下NDK編譯:

編譯的so可用於Android Studio進行鏈接
1.下載ndk:https://developer.android.google.cn/ndk/downloads/
在這裏插入圖片描述
2.解壓
3.配置系統環境變量
#vim /etc/profile 在文件末尾添加如下
export ANDROID_NDK=“ndk路徑”
export PATH="$ANDROID_NDK:$PATH"
4.更新系統變量
#source /etc/profile
5.檢查ndk環境配置正確與否
#ndk-build //出現如下界面即配置成功
AndroidNDK: Could not find application project directory !
Android NDK: Please define the NDK_PROJECT_PATH variable topoint to it.
/xxx:
* Android NDK: Aborting . Stop.

NDK編譯so:

//ndk-build命令 根據jni目錄下的Android.mk進行編譯
#mkdir jni
#cd jni
例子如下:
#vim Android.mk

//my-dir宏返回Android.mk所在位置 即將LOCAL_PATH賦值
LOCAL_PATH:=$(call my-dir)
//清理LOCAL_XXX變量的值
include $(CLEAR_VARS)
//模塊名字
LOCAL_MODULE :=testC
//打包給模塊的C/C++源碼 頭文件不用列出 此源文件可以用具體路徑表示
LOCAL_SRC_FILES:=testC.cpp
//編譯輸出 STATIC爲靜態庫 SHARED爲動態庫 BUILD_EXECUTABLE爲可執行程序
include $(BUILD_SHARED_LIBRARY)

#vim testC.h

#ifndef TESTC_H
#define TESTC_H
int testC();
#endif

#vim testC.cpp

#include "testC.h"
int testC(){
    return 6;
}

//ndk-build編譯 APP_ABI爲編譯輸出的不同cpu架構的so
#ndk-build APP_ABI=“armeabi armeabi-v7a arm64-v8a x86 x86_64”
在jni同級路徑下生成libs目錄和obj目錄(libs下即爲剛剛編譯的so)

NDK編譯so並依賴第三方so:
此時將剛剛編譯的libtestC.so作爲第三方so
#vim testCC.h

#ifndef TESTCC_H
#define TESTCC_H
#include "testC.h"
int testCC();
#endif

#vim testCC.cpp

#include "testCC.h"
int testCC(){
    int a= testC();
    if(a==6)
        return 66;
     return 0;
}

#vim Android.mk


LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE :=testC
//因爲鏈接第三方庫,此時源文件爲so
LOCAL_SRC_FILES:=libtestC.so
//鏈接時爲預編譯
include $(PREBUILT_SHARED_LIBRARY)



include $(CLEAR_VARS)
LOCAL_MODULE :=testCC
LOCAL_SRC_FILES:=testCC.cpp
//鏈接的第三方庫
LOCAL_SHARED_LIBRARIES:=testC
include $(BUILD_SHARED_LIBRARY)

#ndk-build APP_ABI=“armeabi armeabi-v7a arm64-v8a x86 x86_64”

**

2.Android Studio ndk-build

**
SDK manager 安裝ndk
在這裏插入圖片描述

項目設置裏查看ndk下載路徑
在這裏插入圖片描述
在這裏插入圖片描述

SDKmanager External Tools 設置編譯命令 javah和ndk-build
javah 根據java class 生成對應的JNI的頭文件.h
ndk-build 依據JNI的頭文件實現的.cpp生成對應的so

在這裏插入圖片描述

Program: $JDKPath$/bin/javah
Parameters: -encoding UTF-8 -d ../jni -jni $FileClass$
Working directory: $SourcepathEntry$\..\java

在這裏插入圖片描述

//program爲ndk路徑 + ndb-build
Program: G:\Android\Sdk\ndk-bundle\ndk-build.cmd
Parameters: NDK_LIBS_OUT=$ModuleFileDir$/src/main/jniLibs
Workingdirectory: $ModuleFileDir$\src\main

在這裏插入圖片描述

在這裏插入圖片描述

jni目錄下編寫 Android.mk,以及對javah命令產生的.h進行函數實現(編寫.cpp)

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述

3.Android Studio 鏈接Linux下NDK編譯的so

將視圖切換爲Project 新建libs來存放鏈接的so
在這裏插入圖片描述

編寫CmakeList.txt

cmake_minimum_required(VERSION 3.4.1)
#定義變量ProjectRoot爲工程根目錄
set(ProjectRoot G:/Android/AndroidStudioProjects/MyApplication)
#將native-lib加入到編譯源中
add_library( native-lib SHARED src/main/cpp/native-lib.cpp )
 #動態方式加載 libtestC.so
add_library(testC SHARED IMPORTED)
#設置鏈接so的路徑,${ANDROID_ABI}爲so文件的cpu架構類型
set_target_properties(testC  PROPERTIES IMPORTED_LOCATION ${ProjectRoot}/app/libs/${ANDROID_ABI}/libtestC.so)
target_link_libraries(native-lib testC)

native-lib.cpp引用so的頭文件,調用函數
在這裏插入圖片描述

4.Android Studio 鏈接JNI的.h和.cpp生成的so

在這裏插入圖片描述

javah命令生成NdkTest的JNI的頭文件

在這裏插入圖片描述
實現.cpp
在這裏插入圖片描述

ndk-build命令生成so 拷貝到指定的庫目錄 (我指定的是libs build.gradle裏指定)
//調用函數需要 NdkTest 與相應的so (JNI 的.h和.cpp只是用於生成so)
此時可以直接在MainActivity 裏通過NdkTest.getString()調用ndk-build生成so裏的函數;

5.Android Studio 鏈接Linux下的NDK編譯的so(JNI的.h和.cpp)

對比上面的 Android Studio 鏈接JNI的.h和.cpp生成的so
僅僅缺少了java.class,即除了將linux下的so導入庫目錄對應cpu架構目錄下,需要再構造一個java.class
借用上面的例子,Linux下的 JNI .h與.cpp
即對應於com_example_linyuan_myapplication_NdkTest.h 和com_example_linyuan_myapplication_NdkTest.cpp;
Linux下 ndk-build 生成 libNdkTest.so ,將so導入Android Studio的庫目錄;
此時我們新建一個java class ,完全參照NdkTest編寫即可;
最後在MainActivity調用NdkTest.getString().

問題:
將第三方so放到app/libs目錄下時,雖然在CMakeList.txt指定了庫的路徑,運行app時仍然出現閃退。
解決方法:
在buiild.gradle buildTypes屬性後面添加
sourceSets{
main{
jniLibs.srcDirs = [‘libs’]
}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章