前文【Android安卓中jni与Java之间传递复杂的自定义数据结构】已经介绍jni编译c++代码且已经成功封装成java,但是c++是以源代码形式继承在app中,本文介绍如何将前述jni c++代码以隐藏源代码封装成aar的形式。
1、aar打包
1.1、新建module
按照流程 File -> New Module -> Android Native Library 顺序,创建一个TrafficProcess的模块,如下图
由于native代码使用了第三方包opencv,将opencv导入,并添加依赖。
1.2、jni c++部分
首先修改 seting中关于opencv的配置
def opencvsdk='./'
include(':opencv')
project(':opencv').projectDir = new File(opencvsdk + '/sdk')
之后在 moduel的 build.gradle中配置有关cmake的编译信息
externalNativeBuild {
cmake {
arguments "-DOpenCV_DIR=" + project(':opencv').projectDir + "/native/jni"
cppFlags '-frtti -fexceptions'
}
}
ndk{
abiFilters 'armeabi-v7a','arm64-v8a'
}
此时,项目能够正常链接opencv库,已经编译abi的库。再将c++源代码复制到cpp目录下,修改CMakeLists.txt如下
cmake_minimum_required(VERSION 3.10)
set(target TrafficProcess)
project(${target} CXX)
#add_library(${target} SHARED test.cpp)
#target_link_libraries(${target}
# ${log-lib} )
set(ANDROID_OPENCV_COMPONENTS "opencv_java" CACHE STRING "")
#message(STATUS "ANDROID_ABI=${ANDROID_ABI}")
find_package(OpenCV REQUIRED COMPONENTS ${ANDROID_OPENCV_COMPONENTS})
include_directories(
${OpenCV_INCLUDE_DIRS}
)
#link_directories( "./libs/release/jni/${ANDROID_ABI}")
add_library(${target} SHARED ############### 动态库
TrafficProcess.cpp
TrafficProcessJni.cpp
)
target_link_libraries(${target}
${log-lib}
${ANDROID_OPENCV_COMPONENTS}
)
注意,由于从之前的项目复制过来,TrafficProcessJni.cpp文件中的jni接口前缀包名命名可能需要修改。
此时的项目是可以编译的,能够正常生成aar包且打包了so库,但是是没有导出任何java接口的。
1.3、java部分
继续将之前封装的Java代码文件TrafficProcess.java
移入到java目录下(注意和TrafficProcessJni.cpp
中命名要对应),且要静态加载生成的库,完整java代码为
package com.magicsky.trafficprocess;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.RotatedRect;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import java.util.ArrayList;
public class TrafficProcess {
// Used to load the 'TrafficProcess' library on application startup.
static {
System.loadLibrary("TrafficProcess");
}
static final int /*CarType*/
CAR = 0, TRUCK = 1, TRAILER = 2, COACH =3;
public static class CarInfo{
public Rect carRect; // 车辆检测矩形框
public float carDetProb; // 车辆检测概率值
public int carType; // 车辆类型
public RotatedRect rrect; // 车辆分割后的最小外接矩形框
// +车辆分割类型
public boolean pseudHead; // 没有检测到车头,随机选择车头或车尾作为最终的朝向
public Rect carheadRect; // 车头矩形框
public float carheadDetProb; // 车头检测概率值
// +车头检测类型
public ArrayList<Point> points; // 最小外界矩形中点模式(4个点)(pseudHead==true, 50-50)
}
public static class TrafficInfo {
public Size imgSize; // 图片尺寸<