天天看點

Android NDK、JNI之--(四)so打包釋出aar

Android NDK、JNI之--(四)so打包釋出aar

    • 一、前言
    • 二、 真香的Android Studio
    • 三、建立hello Module
      • 3.1、建立cpp檔案夾
          • 3.1.1、建立CMakeLists.txt檔案
          • 3.1.2、建立hello.cpp檔案
      • 3.2、配置build.gradle
      • 3.3、建立本地方法
      • 3.4、測試本地方法
    • 四、将hello module打包aar
    • 五、其他工程使用aar
    • 六、總結

一、前言

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

二、 真香的Android Studio

現在AS已經發展到了3.6.3的版本了,我們可以直接建立一個使用JNI的Native C++示例工程,如下圖最後一個Native C++的工程模闆,一路Next,Finish下去即可建立好該工程了。

Android NDK、JNI之--(四)so打包釋出aar

建立的工程跟之前的差別不是很大,在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 ,彈出如下所示:

Android NDK、JNI之--(四)so打包釋出aar

回車後即可在上文的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中直接列印該方法即可,例如最簡單的:

不出意外的話,可以直接在控制台列印出來資訊了,好的,快進。

四、将hello module打包aar

打包的話其實很簡單了,打開AS右側的Gradle,在hello module下點選Tasks->other->assembleRelease,等待AS建構完即可在 hello子產品下的build/outputs/aar檔案夾下看到生成的hello-release.aar檔案了。

将該檔案拷貝出來,我們解壓看看裡面内容如下,生成的so檔案其實在jni目錄下:

Android NDK、JNI之--(四)so打包釋出aar

五、其他工程使用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中。

最後說下,我最近寫的一些文章知識點基本快串聯起來了。下面是相關的文章:

AndroidStudio加速之–(一)構件倉庫Artifactory

Android NDK、JNI之–(四)so打包釋出aar

AndroidStudio加速之–(三)釋出aar到Artifactory

Android 編譯插樁之–自定義Gradle插件

繼續閱讀