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_第1张图片
新建的工程跟之前的区别不是很大,在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 
#include 

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_第2张图片
回车后即可在上文的hello.cpp文件中看到生成的代码了,但是如果在上文.cpp文件中没有配置默认方法的话,这一步就废了无法帮助我们自动生成:

然后记得将生成的代码中的TODO完善,下文中我们就让其返回了一个默认的字符串:

#include 
#include 

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目录下:
Android NDK、JNI之--(四)so打包发布aar_第3张图片

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

你可能感兴趣的:(Android-NDK,NDK,JNI,CMake,so文件,打包aar)