一 ,什么是任务及管理


任务是用户在执行某项工作时与之互动的一系列 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++的代码

Android studio 插件捕获当前进程的调用栈 android studio接口调用_so文件

在Java中声明native方法,c++自动生成方法(Android studio3.2测试)

Android studio 插件捕获当前进程的调用栈 android studio接口调用_android php接口 studio_02

Java native声明的方法及类型在C++中的方法转换如下:

Android studio 插件捕获当前进程的调用栈 android studio接口调用_android php接口 studio_03

可直接调用在Java层调用方法执行C++代码;

C/C++调用Java代码,比如说Java需要知道C++执行的回调结果,异步处理回调数据是和我们在Java中写callback是一样,数据回调之后set值通知实现类的事件; 这个在C中如果被Native调用的Java类是静态类:FindClass通过传java中完整的类名来查找java的class,如果是非静态类:GetObjectClass通过传入jni中的一个java的引用来获取该引用的类型,他们之间的区别是,前者要求你必须知道完整的类名,后者要求在Jni有一个类的引用;

Java代码

Android studio 插件捕获当前进程的调用栈 android studio接口调用_Java_04

在C中定义的jobect和jmethodid及赋值:

Android studio 插件捕获当前进程的调用栈 android studio接口调用_CMake_05

Android studio 插件捕获当前进程的调用栈 android studio接口调用_so文件_06

调用Java方法

Android studio 插件捕获当前进程的调用栈 android studio接口调用_Java_07