JNI/NDK:CMakeLists.txt 構建so庫,匯入三方so庫
阿新 • • 發佈:2018-11-11
本文使用最新的JNI構建工具CMake完成
通過這篇文章,你講學習到:
- camke構建自己的三方so庫
- 學會使用cmake管理自己jni檔案
- 學會使用cmake呼叫三方的so庫
1.CMakeLists.txt 構建so庫
- 建立jni的工具類JniUtils :
- 這個類的原本用途是,在工程裡用來管理jni的方法,和載入so庫用的
- 但是在這裡僅僅只是為了載入so庫
package com.xjd.myapplication;
public class JniUtils {
static {
//一定要有這一句,否則不會生成so庫
System.loadLibrary("goodutil");
}
// public native static String addMethod();
}
- 刪除系統的cpp檔案;建立自己的cpp檔案(goodutil.cpp)和標頭檔案(goodutil.h)
- goodutil.cpp
#include <string> using namespace std; string welcome(){ return "歡迎來到我的so庫"; } int add(int a ,int b){ return (a+b)*11; }
- goodutil.h
#include <string>
using namespace std;
string welcome();
int add(int ,int );
- 配置CMakelist.txt檔案,構建goodutil庫,兩部如下:
cmake_minimum_required(VERSION 3.4.1)
#1.新增自己的so庫goodutil
add_library( goodutil
SHARED
src/main/cpp/goodutil.cpp )
find_library ( log-lib
log )
#設定so庫的輸出路徑
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
#2.新增連結
target_link_libraries( goodutil
${log-lib} )
- 設定需要生成的平臺,這裡只要了一個
- 執行工程,然後就能在build資料夾裡找到so庫
管理Android工程的jni檔案
- 上面的JniUtils.java 在正式的工程中使用如下:包含so庫的載入,和本地方法的宣告;
- 其中jniutils是由jniutils.cpp構建的so庫,jniutils.cpp是按照jni介面的規範寫的。
- jniutils.cpp內可以引用三方的so庫,三方的庫不用安裝jni的規範些,因為三方的庫是用 jniutils.cpp封裝後提供給java呼叫的
- JniUtils .java可以直接呼叫,呼叫是根據(包名_類名_方法)名尋找的
- 其中jniutils是由jniutils.cpp構建的so庫,jniutils.cpp是按照jni介面的規範寫的。
package com.xjd.ndkt;
public class JniUtils {
static {
System.loadLibrary("jniutils");
// System.loadLibrary("vvw");
}
public static native String getName();
public static native String getvalue(String a,String b);
public static native int add(int a, int b);
public static native int myAdd(int a, int b);
}
- 專案載入自己的so庫,可以刪掉專案自帶的native-lib.cpp,然後自己新建立;也可以吧專案自帶的檔案內自帶的方法刪除(自帶的方法是關聯MainActivity的,我把現在為了統一關聯jni方法,要讓他關聯JniUtils )
- JniUtils.java 和 JniUtils.cpp關係如下圖:
- 由圖中可知,如果是自己按照jni規則構建的soku(就是JniUtils.cpp),可以直接用JniUtils.java類呼叫,但是JniUtils.java要放在對應的包下,而且類名還不可以改
- (就是把別人apk解壓拿到檔案的so庫{這個so庫本質就是JniUtils.cpp},和別人封裝好的呼叫so庫的Java類{這個java類的本質就是JniUtils.java},然後把java類放進類中註明的包中,就可以在工程中通過這個java類呼叫別人寫的so庫,但是這樣沒有文件只能靠猜了,那個美圖秀秀的so庫就是可以這麼用)
- 如果有修改系統自帶的native-lib.cpp的名字那麼就要配置Cmakelist.text檔案,比如本檔案修改成了JniUtils.cpp了所以:
- 1.新增自己建立的庫
- 2.設定庫連結
- 1.新增自己建立的庫
匯入三方的so庫
- 把三方的庫放入jniLibs資料夾下
- 新增生成的平臺,這裡就添加了一個
ndk{
abiFilters 'armeabi-v7a'
}
- 配置 CMakeLists.txt 了,一共4部,如下:
#1.新增三方庫(型別時IMPORTED)
add_library( goodutil
SHARED
IMPORTED )
#2.新增庫的路徑
set_target_properties(
goodutil
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libgoodutil.so )
#3.新增標頭檔案
include_directories(scr/main/cpp/include/ )
#4.新增連結
target_link_libraries( jniutils
goodutil
${log-lib} )
- 按照 CMakeLists.txt 配置的標頭檔案路徑新增三方庫的標頭檔案(就是第一步的時候生成的標頭檔案)
- 完成,Shift+F10執行