任务是用户在执行某项工作时与之互动的一系列 Activity 的集合。
一、步骤,修改build.gradle,添加cmakelists,写JNI接口,写c++,这个是不是流水线的方式集成,不了解每一步是做什么的;
.so文件
so是shared object的缩写,见名思义就是共享的对象,机器可以直接运行的二进制代码。
我们通过C/C++开发的软件,如果以动态链接库的形式输出,那么在Android中它的输出就是一个.so文件。
相比于.a,.so文件是在运行时,才会加载的。所以,当我们将.so文件放入工程时,一定有一段Java代码在运行时,load了这个native库,并通过JNI调用了它的方法。
所以,当我们使用JNI开发时,我们就是在开发一个.so文件。不论我们是开发一个工程,还是开发一个库,只要当我们使用C++开发,都会生成对应的.so文件。
所以JNI开发的核心是,我们生成so的过程,和使用so的过程。
生成.so文件
当我们在新建工程过程中,选中support c++时,系统会为我们写好一些配置
build.gradle
android { compileSdkVersion 29 defaultConfig { minSdkVersion 22 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "android.test.runner.AndroidJUnitRunner" consumerProguardFiles 'consumer-rules.pro' externalNativeBuild { cmake { cppFlags "-fexceptions" abiFilters "armeabi-v7a" } } ndk{ abiFilters"armeabi-v7a" } } externalNativeBuild { cmake { path "src/main/cpp/CMakeLists.txt" version "3.10.2" } } compileOptions { sourceCompatibility = 1.8 targetCompatibility = 1.8 } sourceSets{ main{ jniLibs.srcDirs'libs' } } repositories { flatDir { dirs 'libs' } }}
这是module的build.gradle中的一段。其中,两个externalNativeBuild与ndk是与JNI相关的配置。
我们写好的.cpp/.h文件需要经过编译才能生成.so,让apk得以调用。在编译生成.so文件的过程中,我们可以添加如下一些配置。
cppFlags
cmake时的额外参数,
cppFlags "-fexceptions"
来支持C++异常。
abiFilters
设置 执行 gradle assembleRelease 时,支持的 SO 库构架。如果像上面的代码这样设置,我们打出来的包,就会包含三种架构的.so包。这必然会使APK包体积变大。可以考虑使用productFlavors进行优化。
cmake.path
指定cmakelists文件的路径。
除了这些必须的标签外,externalNativeBuild中还有很多可以配置的东西,因为不是必需,不在此赘述。如ndkBuild中可以设置c++的版本等配置。
CMakeLists.txt
# For more information about using CMake with Android Studio, read the# documentation: https://d.android.com/studio/projects/add-native-code.html# Sets the minimum version of CMake required to build the native library.cmake_minimum_required(VERSION 3.4.1)# Creates and names a library, sets it as either STATIC# or SHARED, and provides the relative paths to its source code.# You can define multiple libraries, and CMake builds them for you.# Gradle automatically packages shared libraries with your APK.add_library(comm_lib SHARED IMPORTED)
set_target_properties(comm_lib PROPERTIES IMPORTED_LOCATION ../../../../libs/${ANDROID_ABI}/libcomm_lib.so)
add_library( # Sets the name of the library. native-lib # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). native-lib.cpp )# Searches for a specified prebuilt library and stores the path as a# variable. Because CMake includes system libraries in the search path by# default, you only need to specify the name of the public NDK library# you want to add. CMake verifies that the library exists before# completing its build.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 )# Specifies libraries CMake should link to your target library. You# can link multiple libraries, such as libraries you define in this# build script, prebuilt third-party libraries, or system libraries.target_link_libraries( # Specifies the target library. native-lib comm_lib # Links the target library to the log library # included in the NDK. ${log-lib} )
在cpp目下编写c++的代码
在Java中声明native方法,c++自动生成方法(Android studio3.2测试)
Java native声明的方法及类型在C++中的方法转换如下:
可直接调用在Java层调用方法执行C++代码;
C/C++调用Java代码,比如说Java需要知道C++执行的回调结果,异步处理回调数据是和我们在Java中写callback是一样,数据回调之后set值通知实现类的事件; 这个在C中如果被Native调用的Java类是静态类:FindClass通过传java中完整的类名来查找java的class,如果是非静态类:GetObjectClass通过传入jni中的一个java的引用来获取该引用的类型,他们之间的区别是,前者要求你必须知道完整的类名,后者要求在Jni有一个类的引用;
Java代码
在C中定义的jobect和jmethodid及赋值:
调用Java方法