跟魚八學NDK開發 基於Cmake(二) 附有第三方動態庫編寫本身的動態庫.so

愛開發,愛魚八! 我是yubaKevin!不是單身的程序猿! 主題:NDK開發 完美解析詳細開發過程,菜鳥必備!android

由於太菜,因此想寫文章學習,提高本身幫助他人!如若文章有誤,請大佬提筆賜教,不慎感激!c++

隨便轉載,可是必定要附上原文連接哦,註上做者:@yubakevingit

個人github地址:github.com/YubaKevin 項目Demo在Trip-for-android裏面,記得來個star哦github

詳細參考資料:developer.android.com/studio/proj…bash


本篇文章開發工具:AS 3.0.1 NDK版本 17

NDK開發基於CMakeLists

1、在As 3.0.1中使用C代碼的第三方動態庫編譯屬於本身的.so

1.配置項目結構

  • main下創建 jniLibs 文件夾,接着在jniLibs下新建.so對應的ABI文件夾(個人ABI是 armeabi-v7a) 用於存放第三方動態.so庫 (必定要對應,這個的很重要)app

  • b.cpp下建立include文件 用於放.h頭文件 (如有其餘cpp文件 放置在cpp文件夾下,建立include只是便於區分管理)工具

項目結構圖以下:post

項目結構圖


2.配置app下的buildgradle

在android{ } 內中配置
defaultConfig {    
   	    externalNativeBuild {
            cmake {
                 abiFilters "x86_64" "armeabi-v7a" "arm64-v8a"			//能夠所有 也能夠任選其一,和.so要對應起來
                cppFlags "-frtti -fexceptions"
            }
        }
        
           sourceSets {
            main {
                jniLibs.srcDirs = ['src/main/jniLibs']
            }
        }
                }
          
        buildTypes {
        debug{
            minifyEnabled false
            ndk {
                abiFilters "x86_64" "armeabi-v7a" "arm64-v8a"        //能夠所有 也能夠任選其一,和.so要對應起來
            }
        }
        release {
            ndk {
                 abiFilters "x86_64" "armeabi-v7a" "arm64-v8a"		//能夠所有 也能夠任選其一,和.so要對應起來
            }

            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

    }

複製代碼

3.配置cmakeLists

#我這裏配置的是多個.so,若是你只是一個,只要複製一行就能夠了
		# CMake版本信息
		cmake_minimum_required(VERSION 3.4.1)

		# 支持-std=gnu++11 也能夠換用換用--std=c++11 對c++ 11的支持
		set(CMAKE_VERBOSE_MAKEFILE on)
		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")

		# 工程路徑 絕對路徑 能夠不定義使用絕對路徑,直接使用 ${CMAKE_SOURCE_DIR}
		set(pathToProject G:/ASworkSpace/CommunicationTest/Communication)

		# 配置加載native依賴 (頭文件)
		include_directories(${pathToProject}/app/src/main/cpp/include)

		# 添加待編譯的文件 使用相對路徑 :${CMAKE_SOURCE_DIR}/src/main/cpp/interface.cpp
		add_library(
		native-lib 
		SHARED             
		${pathToProject}/app/src/main/cpp/interface.cpp
		${pathToProject}/app/src/main/cpp/msl.cpp
		${pathToProject}/app/src/main/cpp/native-lib.cpp )

		# 動態方式加載
		add_library(lib_one SHARED IMPORTED)
		add_library(lib_two SHARED IMPORTED)
		add_library(lib_three SHARED IMPORTED)
		add_library(lib_four SHARED IMPORTED)
		add_library(lib_five SHARED IMPORTED)

		# 引入so文件
		set_target_properties(lib_one PROPERTIES IMPORTED_LOCATION ${pathToProject}/app/src/main/jniLibs/${ANDROID_ABI}/libTcpCommunication.so )
		set_target_properties(lib_two PROPERTIES IMPORTED_LOCATION  ${pathToProject}/app/src/main/jniLibs/${ANDROID_ABI}/libevent.so)
		set_target_properties(lib_three PROPERTIES IMPORTED_LOCATION  ${pathToProject}/app/src/main/jniLibs/${ANDROID_ABI}/libevent_pthreads.so)
		set_target_properties(lib_four PROPERTIES IMPORTED_LOCATION ${pathToProject}/app/src/main/jniLibs/${ANDROID_ABI}/libGCLogger.so)
		set_target_properties(lib_five PROPERTIES IMPORTED_LOCATION ${pathToProject}/app/src/main/jniLibs/${ANDROID_ABI}/libMsgSessionLayer.so)

		#查找庫所在目錄
		find_library( # Sets the name of the path variable.
              log-lib
              log )
		#連接庫 
		target_link_libraries(   native-lib
                         lib_one
                         lib_two
                         lib_three
                         lib_four
                         lib_five  
                         ${log-lib})
複製代碼

CMakeLists圖以下: 黃色箭頭是須要關注的地方,lib_one 這裏屬於自定義命名 學習

CMakeLists圖

4.建立jni類,使用第三方動態庫的.so方法

  • a.在包下建立MyJniUtils包,再建立jniUtils類 (建議統一包名便於後期維護,這裏要注意一下,後面會講到) 開發工具

    jni類

  • b.書寫jni類接口代碼 建議這裏使用單例模式

public  class JniUtils {
    	static {
   	    System.loadLibrary("native-lib");
    	        }
    	public static native String stringFromJNI();
    	public static native int adds();
                        }
複製代碼
  • c.在adds()報紅處,利用alt+enter 快速生成cpp下jni方法 注意jni方法的路徑com.example.kevin.MyJniUtils.JniUtils
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_kevin_MyJniUtils_JniUtils_adds(JNIEnv *env, jclass type) {
return add(3,3);  	//add方法的實現是在.so裏完成的,實現的是所傳值的加法運算
                    //這裏主要是實現C++方法等
}
複製代碼
  • d.在MainActity下調用 JniUtils.adds()
  • e.運行成功後,生成的.so 在 app\build\intermediates\cmake\debug\obj\armeabi-v7a\libnative-lib.so

5.總結

這裏作一個總結,過程看起來繁瑣其實熟練後很簡單
	就分爲四步:
	1.配置項目結構,放置須要的.so文件
	2.配置bulidgradle和CMakeLists
	3.建立jni類包,建立jniUtils,書寫對應接口。在cpp文件下調用.so方法
	4.運行調試
	PS:注意寫的時候要細心,有bug耐心解決,總會成功的。我也是經歷了無數奇葩問題的(抱頭哭)
複製代碼

此時此刻 你必定寫出了基礎的Demo!

準備開始使用你本身的.SO吧!

我是魚八,有任何問題均可在下方討論!謝謝!


附:如下三篇文章,均是基礎內容,大佬看了有話說,菜鳥看了有所獲!

跟魚八學NDK開發 基於Cmake(一) NDK環境配置

跟魚八學NDK開發 基於Cmake(二) 附有第三方動態庫編寫私有的動態庫.so

跟魚八學NDK開發 基於Cmake(三) 使用本身編寫的動態庫.so

相關文章
相關標籤/搜索