1. 程式人生 > >JNI/NDK:CMakeLists.txt 構建so庫,匯入三方so庫

JNI/NDK:CMakeLists.txt 構建so庫,匯入三方so庫

本文使用最新的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可以直接呼叫,呼叫是根據(包名_類名_方法)名尋找的
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.設定庫連結
      在這裡插入圖片描述

匯入三方的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執行