Android NDK、JNI之--(四)so打包發佈aar

一、前言

突然好久發現沒寫JNI相關的代碼了,也不清除現在的一個流程了,所以今天特地重新嘗試了下so文件的開發以及打包發佈aar等流程。

二、 真香的Android Studio

現在AS已經發展到了3.6.3的版本了,我們可以直接新建一個使用JNI的Native C++示例工程,如下圖最後一個Native C++的工程模板,一路Next,Finish下去即可創建好該工程了。
在這裏插入圖片描述
新建的工程跟之前的區別不是很大,在main下多了一個 cpp 的文件夾,專門用來存放 .cpp代碼 以及 CMakeLists.txt文件
直接運行就能看到效果了,但是由於我們要打aar的包,所以我們新建module來做。

三、新建hello Module

直接新建Android Library Module,新建完後我們仿照工程中app module的示例代碼來完善。

3.1、新建cpp文件夾

在hello module的main文件夾下創建cpp文件夾,這個文件夾中需要包含CMakeLists.txt和.cpp的源碼文件,然後我們來完善這個文件夾。

3.1.1、新建CMakeLists.txt文件

我們仿照app module中編寫CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.4.1)

add_library( # Sets the name of the library.
		#注意這裏的library name,下文在java(kotlin)類中需要用到
        hello-lib 

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        hello.cpp) #注意是路徑,而不是包,不可用.區分,需要使用/

find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

target_link_libraries( # Specifies the target library.
        hello-lib

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

可以看到我們在該文件中配置了生成的library名稱爲:hello-lib,而使用的代碼文件是hello.cpp文件。

3.1.2、新建hello.cpp文件

好了接下來新建.cpp文件,裏面是一個示例的hi()方法【爲啥要加這個方法進去?因爲我在新的module中創建java或者kotlin類後,在類中新建本地方法,結果發現快捷鍵無法直接生成對應的c++方法。但是隻要這個cpp文件有任意一個方法後,在本地方法上使用快捷鍵就可以直接生成了】:

#include <jni.h>
#include <string>

extern "C"
JNIEXPORT void JNICALL
Java_xxx_hi(JNIEnv *env, jobject thiz) {
    // TODO: implement hi()
}

3.2、配置build.gradle

打開hello Module下的build.gradle文件,我們仿照app中的進行修改,其實就兩處:

  • android 節點下添加externalNativeBuild 配置path及version等信息
  • android defaultConfig 節點下添加externalNativeBuild 配置cppFlags等信息

修改完畢後重新構建下項目:

android {
		......
		defaultConfig{
				......
				externalNativeBuild {
            		cmake {
                		cppFlags ""
            		}
        		}
		}

		externalNativeBuild {
       		cmake {
            		path "src/main/cpp/CMakeLists.txt" //這裏就是上文我們在module中編寫的hello CMakeLists.txt文件
            		version "3.10.2"
        	}
    }
}

3.3、新建本地方法

在hello Module中java文件夾下的包中新建showHello類(kotlin示例)如下:

class ShowHello {

    companion object {
        init {
            System.loadLibrary("hello-lib")
        }
    }

    external fun getHello(): String
}

伴生對象init{}代碼塊中的就是我們需要加載的library名稱,需要和你在CMakeLists.txt中定義Library 名稱的一致。
然後我們寫本地方法getHello(),此時在getHello()方法上使用快捷鍵 Alt+Enter ,彈出如下所示:
在這裏插入圖片描述
回車後即可在上文的hello.cpp文件中看到生成的代碼了,但是如果在上文.cpp文件中沒有配置默認方法的話,這一步就廢了無法幫助我們自動生成:

然後記得將生成的代碼中的TODO完善,下文中我們就讓其返回了一個默認的字符串:

#include <jni.h>
#include <string>

extern "C"
JNIEXPORT void JNICALL
Java_xxx_hi(JNIEnv *env, jobject thiz) {
    // TODO: implement hi()
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_cooloongwu_hello_ShowHello_getHello(JNIEnv *env, jobject thiz) {
    // TODO: implement getHello()
    return env->NewStringUTF("This is a String from hello module, hello.cpp");
}

3.4、測試本地方法

讓app module直接依賴hello module,然後在MainActivity中直接打印該方法即可,例如最簡單的:

Log.e("本地方法測試", ShowHello().getHello())

不出意外的話,可以直接在控制檯打印出來信息了,好的,快進。

四、將hello module打包aar

打包的話其實很簡單了,打開AS右側的Gradle,在hello module下點擊Tasks->other->assembleRelease,等待AS構建完即可在 hello模塊下的build/outputs/aar文件夾下看到生成的hello-release.aar文件了。
將該文件拷貝出來,我們解壓看看裏面內容如下,生成的so文件其實在jni目錄下:
在這裏插入圖片描述

五、其他工程使用aar

新建其他Android工程,然後我們直接將上文生成的 hello-release.aar包拷貝到新工程app module的libs目錄下,然後更改app module下的build.gradle文件,添加對該aar包的依賴:

dependencies {
	...
	implementation files('libs/hello-release.aar')
}

然後構建項目。
構建完畢後直接在MainActivity中日誌打印調用aar中的ShowHello類的getHello()方法即可測試。

六、總結

好了,整個打包及使用的過程到這裏就結束了。但是每次這樣打包下發給其他人去更新去使用的話是不是很麻煩呢,而且也沒有個版本號信息什麼的,不方便查閱。所以我們可不可以發佈這個aar包到公司構件倉庫中,然後配置依賴去使用呢,當然可以哈哈。如果對構件倉庫還不熟悉的請參考 AndroidStudio加速之–構件倉庫Artifactory 這篇文章,下文我們就將aar發佈到Artifactory中。

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