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下去即可建立好該工程了。
建立的工程跟之前的差別不是很大,在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中直接列印該方法即可,例如最簡單的:
不出意外的話,可以直接在控制台列印出來資訊了,好的,快進。
四、将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中。
最後說下,我最近寫的一些文章知識點基本快串聯起來了。下面是相關的文章:
AndroidStudio加速之–(一)構件倉庫Artifactory
Android NDK、JNI之–(四)so打包釋出aar
AndroidStudio加速之–(三)釋出aar到Artifactory
Android 編譯插樁之–自定義Gradle插件