引言
在C++和Android项目移植过程中,内存共享是提高性能、减少数据拷贝的关键技术。本文解决了Windows 与 Android 平台处理内存共享问题,采用了会话管理机制保存了同一状态;还解决了C++项目移植在Android项目中依赖过多的问题,采用了Pimpl(Pointer to Implementation)设计模式 来隐藏实现细节,减少头文件依赖:
Windows平台C++进程间的内存共享
C++与Java间的内存共享(通过JNI)
一、Windows与Android内存共享实现
WIndows平台调用
在windows中,MeasurementCalcStep1
和 MeasurementCalcStep2
共享同一个 handle
,而在 Android 中这两个步骤被分成了独立的 JNI 调用,导致 handle
状态丢失。
void* handle;
//第一步
bool AstriRoomMeasurementWrapper::MeasurementCalcStep1(const CHAR* scene_path,const CHAR* mesh_output_path,
const CHAR* direpath, const CHAR* contour_xml)
{
SetHardwareType(0);
const std::string scenePath = scene_path;
const std::string meshPath = mesh_output_path;
const std::string direPath = direpath;
const std::string tmp_room_contour_xml = contour_xml;
mylog("\n\n\nMeasurementCalcStep1 Params to calc:");
mylog("scene_path:" + scenePath);
mylog("direpath:" + direPath);
mylog("tmp_room_contour_xml:" + tmp_room_contour_xml);
EnabledNewMeasureId(true);
SetHardwareType(0);
mylog("Calc Measurement start");
handle = InitRoomScene();
if (handle == nullptr) {
mylog("InitRoomScene handle null!!!");
return false;
}
bool res = ParseRoomScene(handle, scenePath, direPath, meshPath);
if (!res) {
mylog("ParseRoomScene fail");
return false;
}
bool isXml = GetRoomContour(handle, tmp_room_contour_xml);
mylog("GetRoomContour result:"+ isXml);
return isXml;
}
//第二步
bool AstriRoomMeasurementWrapper::MeasurementCalcStep2(const CHAR* json_output_path, const CHAR* match_xml)
{
MeasurementResult* result = new MeasurementResult();
std::string room_contour = match_xml;
std::string jsonPath = json_output_path;
mylog("\n\n\MeasurementCalcStep2 Params to calc:");
mylog("match_xml:" + room_contour);
mylog("jsonPath:" + jsonPath);
bool res = RoomMeasurement(handle, result, room_contour);
if (!res) {
mylog("RoomMeasurement fail");
delete result;
return false;
}
//GetMeasurementResult
res = JsonFormat(result, jsonPath);
if (!res) {
mylog("JsonFormat fail");
delete result;
return false;
}
ReleaseRoomScene(handle);
delete result;
return true;
}
解决方案:跨平台状态管理
1.修改MeasurementHelper类
注释掉了类的构造和析构函数,增加了CreateSession和ReleaseSession会话管理器函数。
class MeasurementHelper
{
public:
/*MeasurementHelper() { handle = new MeasurementProcess(); }
~MeasurementHelper()
{
log_file_close();
delete handle; handle = nullptr;
}*/
MeasurementHelper() : handle(nullptr) {}
~MeasurementHelper() {
ReleaseSession();
}
void* CreateSession() {
if (handle) {
return nullptr;
}
handle = new MeasurementProcess();
if (!handle) {
return nullptr;
}
return static_cast<void*>(handle);
}
void ReleaseSession() {
if (handle) {
log_file_close();
delete handle;
handle = nullptr;
scene_path.clear();
output_path.clear();
}
}
MeasurementHelper(const MeasurementHelper&) = delete;
MeasurementHelper& operator=(const MeasurementHelper&) = delete;
MeasurementHelper(MeasurementHelper&& other) noexcept
: handle(other.handle),
alignmentres(std::move(other.alignmentres)),
scene_path(std::move(other.scene_path)),
output_path(std::move(other.output_path))
{
other.handle = nullptr;
}
MeasurementHelper& operator=(MeasurementHelper&& other) noexcept {
if (this != &other) {
ReleaseSession();
handle = other.handle;
alignmentres = std::move(other.alignmentres);
scene_path = std::move(other.scene_path);
output_path = std::move(other.output_path);
other.handle = nullptr;
}
return *this;
}
MeasurementProcess* GetHandle() { return handle; }
bool Measurement(MeasurementResult* result, MeasurementResult_1* result_1, std::string room_contour_xml)
{
MeasurementProcess::OpenLogFile(output_path.substr(0, output_path.find_last_of("/")) + "/measureWithdrawinglog");
log_info("The path of measureWithDrawinglog: %s", (output_path.substr(0, output_path.find_last_of("/")) + "/measureWithdrawinglog").c_str());
log_info("Start measurement!!!");
bool res = false;
log_info("Measurement: before res = handle->Measurement");
res = handle->Measurement(&alignmentres, true, room_contour_xml);
log_info("Measurement: after res = handle->Measurement");
if (!res)
return res;
if(IsOPTIMIZE_HOLE_BY_IMAGE())
#ifdef OPTIMIZE_HOLE_BY_IMAGE
#ifdef _WIN32
make_shared<IPlaneLineByRgbd>(alignmentres, *handle);
#endif
#endif
log_info("Measurement: before MeasurementResult");
MesurementResult(result, result_1, handle);
log_info("Measurement: after MeasurementResult");
AlignmentResultToMesurementResult(result, alignmentres);
log_info("Measurement: after AlignmentResultToMeasurementResult");
std::vector<std::string> mesh_list;
bool cardflag = false;
log_info("Measurement: start save plane mesh");
if (handle->SavePlaneMesh(scene_path, scene_path, alignmentres, mesh_list, output_path, result->cad_door, result->cad_window, cardflag))
res = true;
log_info("Measurement: save plane mesh successfully");
return res;
}
bool GetContourXML(const std::string& xml_path)
{
//xml_path = output_path + "/contour.xml";
//xml_path = "tmp_room_contour.xml";
std::cout << "xml_path:" << xml_path << std::endl;
//std::cout << "===test===" << std::endl;
return handle->GetRoomContour(xml_path, &alignmentres);
}
bool ParseScene(std::string scene_path, std::string compass_path, std::string path)
{
MeasurementProcess::OpenLogFile(path.substr(0, path.find_last_of("/")) + "/parseScenelog");
cout << "%$@#&^$* The path of the parseScenelog: " << path.substr(0, path.find_last_of("/")) << "/parseScenelog" << endl;
log_info("The Path of ParseScenelog: %s", (path.substr(0, path.find_last_of("/")) + "/parseScenelog").c_str());
log_info("Start Parse Scene!!!");
this->scene_path = scene_path;
this->output_path = path;
g_meshPath = path;
#ifdef _WIN32
imagePath = path.substr(0, path.find_last_of("\\")) + "\\contour.jpg";
#else
imagePath = path.substr(0, path.find_last_of("/")) + "/contour.jpg";
#endif
cloudPath = scene_path;
CCompass compass;
compass.ReadCompassByTxt(compass_path);
log_info("Read Compass By Txt!!!");
s_MeasurementErrorCode = MEASUREMENT_SUCCESS;
handle->SetCustomerName(MEASUREMENT_CUSTOMER_UNRE);
log_info("Get handle success!!!");
return handle->ParseScene(scene_path, "", &alignmentres);
}
private:
MeasurementProcess* handle;
//MeasurementResult result;
AlignmentResult alignmentres;
std::string scene_path;
std::string output_path;
};
2.创建了全局管理器
MeasurementSessionManager.h
#ifndef MEASUREMENT_SESSION_MANAGER_H
#define MEASUREMENT_SESSION_MANAGER_H
#include <map>
#include <mutex>
#include <memory>
#include "MeasurementAPI.h"
class MeasurementSessionManager {
public:
static MeasurementSessionManager& Instance() {
static MeasurementSessionManager instance;
return instance;
}
void* CreateSession();
MeasurementHelper* GetHelper(void* sessionHandle);
bool ReleaseSession(void* sessionHandle);
void ReleaseAllSessions();
MeasurementSessionManager(const MeasurementSessionManager&) = delete;
MeasurementSessionManager& operator=(const MeasurementSessionManager&) = delete;
private:
MeasurementSessionManager() = default;
std::map<void*, std::unique_ptr<MeasurementHelper>> sessions_;
std::mutex mutex_;
};
#endif // MEASUREMENT_SESSION_MANAGER_H
MeasurementSessionManager.cpp
#include "MeasurementSessionManager.h"
void* MeasurementSessionManager::CreateSession() {
std::lock_guard<std::mutex> lock(mutex_);
auto helper = std::make_unique<MeasurementHelper>();
void* handle = helper->CreateSession();
if (!handle) {
return nullptr;
}
sessions_[handle] = std::move(helper);
return handle;
}
MeasurementHelper* MeasurementSessionManager::GetHelper(void* sessionHandle) {
std::lock_guard<std::mutex> lock(mutex_);
auto it = sessions_.find(sessionHandle);
if (it != sessions_.end()) {
return it->second.get();
}
return nullptr;
}
bool MeasurementSessionManager::ReleaseSession(void* sessionHandle) {
std::lock_guard<std::mutex> lock(mutex_);
auto it = sessions_.find(sessionHandle);
if (it != sessions_.end()) {
it->second->ReleaseSession();
sessions_.erase(it);
return true;
}
return false;
}
void MeasurementSessionManager::ReleaseAllSessions() {
std::lock_guard<std::mutex> lock(mutex_);
for (auto& pair : sessions_) {
pair.second->ReleaseSession();
}
sessions_.clear();
}
二、使用Pimpl设计模式,去除MeasurementProcess.h依赖
由于在MeasurementHelper类中引用了MeasurementProcess结构体在MeasurementProcess.h中,而MeasurementProcess.h文件中依赖耦合了过多的头文件,所以采用了Pimpl设计模式,分离出来了需要的函数,避免输出的头文件中依赖耦合过多的文件导致难以移植。
对上述代码中MeasurementHelper类的实现,分别在.h和.cpp文件中做了以下修改
改造步骤
创建实现类封装细节
将MeasurementHelper
的实现细节转移到独立的实现类中。使用前置声明替代头文件包含
在头文件中用前置声明代替#include "MeasurementProcess.h"
。分离接口与实现
通过指针间接访问核心功能,避免暴露内部依赖。
DLL.h
/*
Function:MeasurementHelper with drawing matching
*/
class MeasurementHelper {
public:
MeasurementHelper();
~MeasurementHelper();
MeasurementHelper(const MeasurementHelper&) = delete;
MeasurementHelper& operator = (const MeasurementHelper&) = delete;
MeasurementHelper(MeasurementHelper&& other) noexcept;
MeasurementHelper& operator = (MeasurementHelper&& other) noexcept;
void* CreateSession();
void ReleaseSession();
bool Measurement(MeasurementResult* result, MeasurementResult_1* result_1, std::string room_contour_xml);
bool GetContourXML(const std::string& xml_path);
bool ParseScene(std::string scene_path, std::string compass_path, std::string path);
private:
struct Impl;
std::unique_ptr<Impl> impl;
};
DLL.cpp 实现
struct MeasurementHelper::Impl{
MeasurementProcess* handle = nullptr;
AlignmentResult alignmentres;
std::string scene_path;
std::string output_path;
void* CreateSession() {
if (handle) return nullptr;
handle = new MeasurementProcess();
return static_cast<void*>(handle);
}
void ReleaseSession() {
if (handle) {
log_file_close();
delete handle;
handle = nullptr;
scene_path.clear();
output_path.clear();
}
}
bool Measurement(MeasurementResult* result, MeasurementResult_1* result_1, std::string room_contour_xml)
{
MeasurementProcess::OpenLogFile(output_path.substr(0, output_path.find_last_of("/")) + "/measureWithdrawinglog");
log_info("The path of measureWithDrawinglog: %s", (output_path.substr(0, output_path.find_last_of("/")) + "/measureWithdrawinglog").c_str());
log_info("Start measurement!!!");
bool res = false;
log_info("Measurement: before res = handle->Measurement");
res = handle->Measurement(&alignmentres, true, room_contour_xml);
log_info("Measurement: after res = handle->Measurement");
if (!res)
return res;
if (IsOPTIMIZE_HOLE_BY_IMAGE())
#ifdef OPTIMIZE_HOLE_BY_IMAGE
#ifdef _WIN32
make_shared<IPlaneLineByRgbd>(alignmentres, *handle);
#endif
#endif
log_info("Measurement: before MeasurementResult");
MesurementResult(result, result_1, handle);
log_info("Measurement: after MeasurementResult");
AlignmentResultToMesurementResult(result, alignmentres);
log_info("Measurement: after AlignmentResultToMeasurementResult");
std::vector<std::string> mesh_list;
bool cardflag = false;
log_info("Measurement: start save plane mesh");
if (handle->SavePlaneMesh(scene_path, scene_path, alignmentres, mesh_list, output_path, result->cad_door, result->cad_window, cardflag))
res = true;
log_info("Measurement: save plane mesh successfully");
return res;
}
bool GetContourXML(const std::string& xml_path)
{
//xml_path = output_path + "/contour.xml";
//xml_path = "tmp_room_contour.xml";
std::cout << "xml_path:" << xml_path << std::endl;
//std::cout << "===test===" << std::endl;
return handle->GetRoomContour(xml_path, &alignmentres);
}
bool ParseScene(std::string scene_path, std::string compass_path, std::string path)
{
MeasurementProcess::OpenLogFile(path.substr(0, path.find_last_of("/")) + "/parseScenelog");
cout << "%$@#&^$* The path of the parseScenelog: " << path.substr(0, path.find_last_of("/")) << "/parseScenelog" << endl;
log_info("The Path of ParseScenelog: %s", (path.substr(0, path.find_last_of("/")) + "/parseScenelog").c_str());
log_info("Start Parse Scene!!!");
this->scene_path = scene_path;
this->output_path = path;
g_meshPath = path;
#ifdef _WIN32
imagePath = path.substr(0, path.find_last_of("\\")) + "\\contour.jpg";
#else
imagePath = path.substr(0, path.find_last_of("/")) + "/contour.jpg";
#endif
cloudPath = scene_path;
CCompass compass;
compass.ReadCompassByTxt(compass_path);
log_info("Read Compass By Txt!!!");
s_MeasurementErrorCode = MEASUREMENT_SUCCESS;
handle->SetCustomerName(MEASUREMENT_CUSTOMER_UNRE);
log_info("Get handle success!!!");
return handle->ParseScene(scene_path, "", &alignmentres);
}
};
MeasurementHelper::MeasurementHelper() : impl(std::make_unique<Impl>()){}
MeasurementHelper::~MeasurementHelper() = default;
MeasurementHelper::MeasurementHelper(MeasurementHelper&& other) noexcept = default;
MeasurementHelper& MeasurementHelper::operator=(MeasurementHelper&& other) noexcept = default;
void* MeasurementHelper::CreateSession() {
return impl->CreateSession();
}
void MeasurementHelper::ReleaseSession() {
impl->ReleaseSession();
}
bool MeasurementHelper::Measurement(MeasurementResult* result, MeasurementResult_1* result_1,
std::string room_contour_xml) {
return impl->Measurement(result, result_1, room_contour_xml);
}
bool MeasurementHelper::GetContourXML(const std::string& xml_path) {
return impl->GetContourXML(xml_path);
}
bool MeasurementHelper::ParseScene(std::string scene_path,
std::string compass_path,
std::string path) {
return impl->ParseScene(scene_path, compass_path, path);
}
三、Android中引用
JNI内存共享架构
整体架构关系
JNI.cpp
本地接口层
实现Java中声明的native方法
在C++中处理Java传入的参数
调用C++核心功能
返回结果给Java层
#include <jni.h>
#include <string>
#include "MeasurementAPI.h"
#include "MeasurementConfig.h"
#include "MeasurementSessionManager.h"
#include "android/log.h"
#define LOG_TAG "native-lib"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
std::string jstringToString(JNIEnv* env, jstring jstr) {
if (!jstr) return "";
const char* cstr = env->GetStringUTFChars(jstr, nullptr);
std::string result(cstr);
env->ReleaseStringUTFChars(jstr, cstr);
return result;
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_unre_SDK_MeasureSDK_StartRoomMeasurement(
JNIEnv* env,
jclass clazz, jstring scene_path, jstring cad_path, jstring compass_path, jstring ruler_json, jstring meshPath, jstring jsonPath) {
LOGI("!!!!!!!!StartMeasurement!!!!!!!!!!! ! %s\n", " 0 ");
std::string hello = "Hello from C++";
const char *Scene_path = env->GetStringUTFChars(scene_path, nullptr);
std::string c_Scene_path =std::string(Scene_path);
//std::string x_Scene_path =JniJavaToStdString(env, scene_path);
const char *Cad_path = env->GetStringUTFChars(cad_path, nullptr);
std::string c_Cad_path = std::string(Cad_path);
const char *Compass_path = env->GetStringUTFChars(compass_path, nullptr);
std::string c_Compass_path = std::string(Compass_path);
const char *Ruler_json = env->GetStringUTFChars(ruler_json, nullptr);
std::string c_Ruler_json = std::string(Ruler_json);
const char *MeshPath = env->GetStringUTFChars(meshPath, nullptr);
std::string c_MeshPath = std::string (MeshPath);
const char *JsonPath = env->GetStringUTFChars(jsonPath, nullptr);
std::string c_JsonPath = std::string (JsonPath);
auto* result = new MeasurementResult();
auto* result_1 = new MeasurementResult_1();
LOGI("路径配置完成 %s\n", " 1 ");
//hello += "Hello from TestRoomMeasurement";
//std::cout << "Hello from TestRoomMeasurement" << std::endl;
LOGI("The path of c_Ruler_json: %s\n", c_Ruler_json.c_str());
SetAllRulersJson(c_Ruler_json);
LOGI("测量模式设置完成 %s\n", " 2 ");
SetHardwareType(0);
bool b;
b = StartMeasurementAndSaveMesh_Android(static_cast<MEASUREMENT_CUSTOMER_NAME>(0x00000001), c_Scene_path, c_Cad_path, result, result_1, c_Compass_path, c_MeshPath);
LOGI("The size of bim_info_hole_details: %zu\n", result->bim_info_hole_details.size());
if (c_JsonPath.empty())
{
return (jstring) L"";
}
// unsigned len = c_JsonPath.size() + 1;
// setlocale(LC_CTYPE, "en_US.UTF-8");
// auto *p = new wchar_t[len];
// mbstowcs(p, c_JsonPath.c_str(), len);
// std::wstring w_JsonPath(p);
// delete[] p;
// LOGI("w_JsonPath: %ls\n", w_JsonPath.c_str());
// std::wcout << "w_JsonPath: " << w_JsonPath.c_str() << std::endl;
LOGI("Start output json!!!");
bool J;
J = JsonFormat(result, result_1, c_JsonPath);
LOGI("Ended output json!!!");
//delete result;
LOGI("If successfully output json: %d\n", J);
// std::string bool_b = &"是否调用成功:" [ b];
LOGI("是否調用成功: %d\n", b);
// return env->NewStringUTF(bool_b.c_str());
env->ReleaseStringUTFChars(scene_path, Scene_path);
env->ReleaseStringUTFChars(cad_path, Cad_path);
env->ReleaseStringUTFChars(compass_path, Compass_path);
env->ReleaseStringUTFChars(ruler_json, Ruler_json);
env->ReleaseStringUTFChars(meshPath, MeshPath);
env->ReleaseStringUTFChars(jsonPath, JsonPath);
env->DeleteLocalRef(scene_path);
env->DeleteLocalRef(cad_path);
env->DeleteLocalRef(compass_path);
env->DeleteLocalRef(ruler_json);
env->DeleteLocalRef(meshPath);
env->DeleteLocalRef(jsonPath);
delete result;
delete result_1;
return env->NewStringUTF(hello.c_str());
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_unre_SDK_MeasureSDK_StartRoomMeasurementFactory(JNIEnv *env, jclass clazz,
jstring scene_path, jstring cad_path,
jstring compass_path, jstring meshPath,
jstring jsonPath) {
// TODO: implement StartRoomMeasurementFactory()
LOGI("!!!!!!!!StartMeasurement!!!!!!!!!!! ! %s\n", " 0 ");
std::string hello = "Hello from C++";
const char *Scene_path = env->GetStringUTFChars(scene_path, nullptr);
std::string c_Scene_path =std::string(Scene_path);
//std::string x_Scene_path =JniJavaToStdString(env, scene_path);
const char *Cad_path = env->GetStringUTFChars(cad_path, nullptr);
std::string c_Cad_path = std::string(Cad_path);
const char *Compass_path = env->GetStringUTFChars(compass_path, nullptr);
std::string c_Compass_path = std::string(Compass_path);
const char *MeshPath = env->GetStringUTFChars(meshPath, nullptr);
std::string c_MeshPath = std::string (MeshPath);
const char *JsonPath = env->GetStringUTFChars(jsonPath, nullptr);
std::string c_JsonPath = std::string (JsonPath);
auto* result = new MeasurementResult();
auto* result_1 = new MeasurementResult_1();
LOGI("路径配置完成 %s\n", " 1 ");
bool b;
b = StartMeasurementAndSaveMesh_Android(static_cast<MEASUREMENT_CUSTOMER_NAME>(0x00000001), c_Scene_path, c_Cad_path, result, result_1, c_Compass_path, c_MeshPath);
LOGI("The size of bim_info_hole_details: %zu\n", result->bim_info_hole_details.size());
if (c_JsonPath.empty())
{
return (jstring) L"";
}
unsigned len = c_JsonPath.size() + 1;
setlocale(LC_CTYPE, "en_US.UTF-8");
auto *p = new wchar_t[len];
mbstowcs(p, c_JsonPath.c_str(), len);
std::wstring w_JsonPath(p);
delete[] p;
LOGI("w_JsonPath: %ls\n", w_JsonPath.c_str());
// std::wcout << "w_JsonPath: " << w_JsonPath.c_str() << std::endl;
LOGI("Start output json!!!");
bool J;
J = JsonFormat(result, result_1, c_JsonPath);
LOGI("Ended output json!!!");
LOGI("If successfully output json: %d\n", J);
// std::string bool_b = &"是否调用成功:" [ b];
LOGI("是否調用成功: %d\n", b);
// return env->NewStringUTF(bool_b.c_str());
env->ReleaseStringUTFChars(scene_path, Scene_path);
env->ReleaseStringUTFChars(cad_path, Cad_path);
env->ReleaseStringUTFChars(compass_path, Compass_path);
env->ReleaseStringUTFChars(meshPath, MeshPath);
env->ReleaseStringUTFChars(jsonPath, JsonPath);
env->DeleteLocalRef(scene_path);
env->DeleteLocalRef(cad_path);
env->DeleteLocalRef(compass_path);
env->DeleteLocalRef(meshPath);
env->DeleteLocalRef(jsonPath);
delete result;
delete result_1;
return env->NewStringUTF(hello.c_str());
}
extern "C"
JNIEXPORT jlong JNICALL
Java_com_unre_SDK_MeasureSDK_createSession(
JNIEnv* env, jclass clazz) {
return reinterpret_cast<jlong>(
MeasurementSessionManager::Instance().CreateSession()
);
}
extern "C"
JNIEXPORT bool JNICALL
Java_com_unre_SDK_MeasureSDK_ParseRoomScene(JNIEnv *env, jclass clazz,
jlong session_handle,
jstring scene_path,
jstring compass_path,
jstring ruler_json,
jstring mesh_path,
jstring contour_xml) {
void* sessionHandle = reinterpret_cast<void*>(session_handle);
auto helper = MeasurementSessionManager::Instance().GetHelper(sessionHandle);
std::string scene = jstringToString(env, scene_path);
std::string compass = jstringToString(env, compass_path);
std::string ruler = jstringToString(env, ruler_json);
std::string mesh = jstringToString(env, mesh_path);
std::string contour = jstringToString(env, contour_xml);
// const char *Scene_path = env->GetStringUTFChars(scene_path, nullptr);
// std::string c_Scene_path = std::string(Scene_path);
//
// const char *Compass_path = env->GetStringUTFChars(compass_path, nullptr);
// std::string c_Compass_path = std::string (Compass_path);
//
// const char *Ruler_json = env->GetStringUTFChars(ruler_json, nullptr);
// std::string c_Ruler_json = std::string (Ruler_json);
//
// const char *Mesh_path = env->GetStringUTFChars(mesh_path, nullptr);
// std::string c_Mesh_path = std::string(Mesh_path);
//
// const char *Contour_xml = env->GetStringUTFChars(contour_xml, nullptr);
// std::string c_Contour_xml = std::string(Contour_xml);
SetAllRulersJson(ruler);
SetHardwareType(0);
bool parseSuccess = helper->ParseScene(scene, compass, mesh);
if (!parseSuccess) {
return JNI_FALSE;
}
// 获取轮廓 XML
bool contourSuccess = helper->GetContourXML(contour);
return contourSuccess ? JNI_TRUE : JNI_FALSE;
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_unre_SDK_MeasureSDK_RoomMeasurement(JNIEnv *env, jclass clazz,
jlong session_handle,
jstring subwall_contour,
jstring jsonPath) {
void* sessionHandle = reinterpret_cast<void*>(session_handle);
auto helper = MeasurementSessionManager::Instance().GetHelper(sessionHandle);
const char *Subwall_contour = env->GetStringUTFChars(subwall_contour, nullptr);
std::string c_Subwall_contour = std::string(Subwall_contour);
const char *JsonPath = env->GetStringUTFChars(jsonPath, nullptr);
std::string c_JsonPath = std::string(JsonPath);
auto* result = new MeasurementResult();
auto* result_1 = new MeasurementResult_1();
bool measureSuccess = helper->Measurement(result,result_1,c_Subwall_contour);
if (!measureSuccess) {
return JNI_FALSE;
}
bool jsonSuccess = JsonFormat(result, result_1,c_JsonPath);
MeasurementSessionManager::Instance().ReleaseSession(sessionHandle);
delete result;
delete result_1;
return jsonSuccess ? JNI_TRUE : JNI_FALSE;
// RoomMeasurement(handle, result, result_1, c_Subwall_contour);
//
// JsonFormat(result, result_1, c_JsonPath);
//
// ReleaseRoomScene(handle);
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_unre_SDK_MeasureSDK_releaseSession(
JNIEnv* env, jclass clazz, jlong session_handle) {
void* sessionHandle = reinterpret_cast<void*>(session_handle);
MeasurementSessionManager::Instance().ReleaseSession(sessionHandle);
}
MeasureSDK.java
Java与C++之间的桥梁
加载本地库
声明native方法接口
封装C++功能为Java可调用的API
testroommeasurement是整合C++项目在cmakelist项目中声明的项目名称。
package com.unre.SDK;
public class MeasureSDK {
static{
System.loadLibrary("testroommeasurement");
}
public static native long createSession();
public static native String StartRoomMeasurement(String scene_path, String cad_path, String compass_path, String ruler_json, String meshPath, String jsonPath);
//factory no ruler_json
public static native String StartRoomMeasurementFactory(String scene_path, String cad_path, String compass_path, String meshPath, String jsonPath);
// public native String testJNI();
public static native boolean ParseRoomScene(
long sessionHandle,
String scenePath, String compassPath,
String rulerJson, String meshPath,
String contourXml);
public static native boolean RoomMeasurement(
long sessionHandle,
String matchXml, String jsonPath);
public static native void releaseSession(long sessionHandle);
}
RoomMeasurementService.java
系统服务的Android实现
作为后台Service长期运行
通过AIDL暴露服务接口
管理测量会话的生命周期
调用MeasureSDK执行实际测量
package com.unre.ucl360.measurementservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import androidx.annotation.Nullable;
import com.unre.SDK.MeasureSDK;
import com.unre.ucl360.BimMatchService.BimMatchAidlInterface;
import java.io.File;
import java.io.InterruptedIOException;
public class RoomMeasurementService extends Service
{
private final RMtAidlInterface.Stub mRMtAidlInterface = new RMtAidlInterface.Stub()
{
BimMatchAidlInterface mBimMatchAidlInterface;
private long currentSessionId = 0;
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException
{
}
@Override
public boolean JRoomMeasurement(String scenePath, String compass_path, String ruler_json, String cad_path, String meshPath, String jsonPath) throws RemoteException
{
File path = new File(jsonPath);
String parentPath = path.getParent();
AssetsCopyTOSDcard assetsCopyTOSDcard = new AssetsCopyTOSDcard(getApplicationContext());
assetsCopyTOSDcard.AssetToSD("config_file", parentPath);
String M_results = MeasureSDK.StartRoomMeasurement(scenePath, cad_path, compass_path, ruler_json, meshPath, jsonPath);
Log.d("TAG","M_results "+M_results);
File jsonFile = new File(jsonPath);
return jsonFile.length() != 0;
}
public boolean JRoomMeasurementFactory(String scenePath, String compass_path, String cad_path, String meshPath, String jsonPath) throws RemoteException
{
File path = new File(jsonPath);
String parentPath = path.getParent();
AssetsCopyTOSDcard assetsCopyTOSDcard = new AssetsCopyTOSDcard(getApplicationContext());
assetsCopyTOSDcard.AssetToSD("config_file", parentPath);
String M_results = MeasureSDK.StartRoomMeasurementFactory(scenePath, cad_path, compass_path, meshPath, jsonPath);
File jsonFile = new File(jsonPath);
return jsonFile.length() != 0;
}
@Override
public void ParseRoomScene(String scenePath, String compass_path,
String ruler_json, String meshPath,
String contour_xml) throws RemoteException {
File meshDir = new File(meshPath);
if (!meshDir.exists()) {
meshDir.mkdirs();
}
AssetsCopyTOSDcard assetsCopy = new AssetsCopyTOSDcard(getApplicationContext());
assetsCopy.AssetToSD("config_file", meshPath);
currentSessionId = MeasureSDK.createSession();
if (currentSessionId == 0) {
Log.e("Measurement", "Failed to create session");
}
boolean success = MeasureSDK.ParseRoomScene(
currentSessionId,scenePath, compass_path, ruler_json, meshPath, contour_xml);
if (!success) {
throw new RemoteException("ParseRoomScene failed");
}
}
public boolean RoomMeasurementAndSaveData(String jsonPath)
{
File Path = new File(jsonPath);
String ParentPath = Path.getParent();
String subwall_contour = ParentPath + "SubWalls.xml";
MeasureSDK.RoomMeasurement(currentSessionId,subwall_contour, jsonPath);
MeasureSDK.releaseSession(currentSessionId);
currentSessionId = 0;
File jsonFile = new File(jsonPath);
return jsonFile.length() != 0;
}
public boolean JRoomMeasurementWithBluePrint(String scenePath, String compass_path, String ruler_json, String meshPath, String contour_xml, String drawPath, String xmlPath, String stage, String stationId, String preMatchPath, String cadId, String xmlId, String matchResult, String jsonPath)
{
String lock = "The first is existed!";
new Thread(()-> {
try{
mRMtAidlInterface.ParseRoomScene(scenePath, compass_path, ruler_json, meshPath, contour_xml);
File file = new File(preMatchPath);
if (!file.exists())
{
for (int i = 0; i < 2; i++)
{
if (mBimMatchAidlInterface != null) {
mBimMatchAidlInterface.JScanMatch(drawPath, xmlPath, stage, stationId, preMatchPath, cadId, xmlId, matchResult);
} else {
Log.e("MainActivity", "BimMatchAidlInterface is not bound.");
}
}
}
else
{
if (mBimMatchAidlInterface != null) {
mBimMatchAidlInterface.JScanMatch(drawPath, xmlPath, stage, stationId, preMatchPath, cadId, xmlId, matchResult);
} else {
Log.e("MainActivity", "BimMatchAidlInterface is not bound.");
}
}
Log.i("before RoomMeasurementAndSaveData", "before RoomMeasurementAndSaveData");
mRMtAidlInterface.RoomMeasurementAndSaveData(jsonPath);
} catch (Exception e) {
throw new RuntimeException(e);
}
synchronized (lock) {
try {
lock.notifyAll();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}, "First").start();
new Thread(()-> {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
try {
mRMtAidlInterface.ParseRoomScene(scenePath, compass_path, ruler_json, meshPath, contour_xml);
File file = new File(preMatchPath);
if (!file.exists())
{
for (int i = 0; i < 2; i++)
{
if (mBimMatchAidlInterface != null) {
mBimMatchAidlInterface.JScanMatch(drawPath, xmlPath, stage, stationId, preMatchPath, cadId, xmlId, matchResult);
} else {
Log.e("MainActivity", "BimMatchAidlInterface is not bound.");
}
}
}
else {
if (mBimMatchAidlInterface != null) {
mBimMatchAidlInterface.JScanMatch(drawPath, xmlPath, stage, stationId, preMatchPath, cadId, xmlId, matchResult);
} else {
Log.e("MainActivity", "BimMatchAidlInterface is not bound.");
}
}
mRMtAidlInterface.RoomMeasurementAndSaveData(jsonPath);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
// lock.notifyAll();
}, "second").start();
return true;
}
// public boolean JRoomMeasurementWithBluePrint(String scenePath, String compass_path, String ruler_json, String contour_xml, String meshPath, String jsonPath)
// {
// boolean ret = MeasureSDK.ParseRoomScene(scenePath, compass_path, ruler_json, meshPath, contour_xml);
//
// if (!ret)
// {
// Log.i("Send error info", "parseRoomScene fail!!");
// }
//
// String lock = "It's a match!";
// new Thread(()->{
// synchronized (lock)
// {
// try{
// lock.notify();
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// },"t1").start();
//
// System.out.println("已通知去匹配了!");
//
// new Thread(()->{
// synchronized (lock)
// {
// try {
// lock.wait();
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
// }
// },"t2").start();
//
// System.out.println("匹配结束,等到匹配结束的信号!");
//
//
// File Path = new File(jsonPath);
// String ParentPath = Path.getParent();
// String match_xml = ParentPath + "match_result.json";
//
// MeasureSDK.RoomMeasurement(match_xml, jsonPath);
//
// return true;
// }
// public boolean JRoomMeasurement_OwnBlueprint(String scenePath, String compass_path, String subwall_contour, String meshPath, String jsonPath)
// {
// MeasureSDK.ParseRoomScene(scenePath, compass_path, meshPath);
//
// MeasureSDK.RoomMeasurement(subwall_contour, jsonPath);
//
// File jsonFile = new File(jsonPath);
// return jsonFile.length() != 0;
// }
};
@Override
public void onCreate()
{
super.onCreate();
// FileUtils.creatPath();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mRMtAidlInterface;
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
AIDL (Android Interface Definition Language) - 跨进程通信层
进程间通信(IPC)的契约定义
定义服务接口和方法签名
生成跨进程通信的代理代码
处理进程间数据编组(marshalling)
/*
* This file is auto-generated. DO NOT MODIFY.
*/
package com.unre.ucl360.measurementservice;
// Declare any non-default types here with import statements
public interface RMtAidlInterface extends android.os.IInterface
{
/** Default implementation for RMtAidlInterface. */
public static class Default implements com.unre.ucl360.measurementservice.RMtAidlInterface
{
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
@Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException
{
}
/**
* JRoomMeasurement函数中的参数皆为路径:
* scenePath: 点云路径,文件类型为 pts、ptsen
* compass_path: 方位文件路径———— dire.txt
* Ruler_json: 用户设置的测量模式————ruler.json
* cad_path: CAD文件路径
* meshPath: 输出mesh.obj相关文件的路径
* jsonPath:output.json输出路径
*/
// no Blueprint
@Override public boolean JRoomMeasurement(java.lang.String scenePath, java.lang.String compass_path, java.lang.String Ruler_json, java.lang.String cad_path, java.lang.String meshPath, java.lang.String jsonPath) throws android.os.RemoteException
{
return false;
}
@Override public boolean JRoomMeasurementFactory(java.lang.String scenePath, java.lang.String compass_path, java.lang.String cad_path, java.lang.String meshPath, java.lang.String jsonPath) throws android.os.RemoteException
{
return false;
}
/**
* The arguements of the API JScanMatch:
* "-d", ------- drawPath
* "-x", ------- xmlPath
* "-s", ------- stage
* "-a", ------- stationId
* "-pm", ------- preMatchPath
* "-im", ------- cadId
* "-is", ------- xmlId
* "-m", ------- resultPath
*/
// Own Blueprint
/**
* The arguements of the API ParseRoomScene
* scene_path, // 点云文件路径
* compass_path, // 方位文件路径
* ruler_json, // 测量规则配置文件
* mesh_path, // 网格输出路径
* contour_xml // 房间轮廓输出路径,输出为XML格式文件
*/
@Override public void ParseRoomScene(java.lang.String scenePath, java.lang.String compass_path, java.lang.String ruler_json, java.lang.String meshPath, java.lang.String contour_xml) throws android.os.RemoteException
{
}
@Override public boolean RoomMeasurementAndSaveData(java.lang.String jsonPath) throws android.os.RemoteException
{
return false;
}
@Override public boolean JRoomMeasurementWithBluePrint(java.lang.String scenePath, java.lang.String compass_path, java.lang.String ruler_json, java.lang.String meshPath, java.lang.String contour_xml, java.lang.String drawPath, java.lang.String xmlPath, java.lang.String stage, java.lang.String stationId, java.lang.String preMatchPath, java.lang.String cadId, java.lang.String xmlId, java.lang.String matchResult, java.lang.String jsonPath) throws android.os.RemoteException
{
return false;
}
@Override
public android.os.IBinder asBinder() {
return null;
}
}
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.unre.ucl360.measurementservice.RMtAidlInterface
{
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.unre.ucl360.measurementservice.RMtAidlInterface interface,
* generating a proxy if needed.
*/
public static com.unre.ucl360.measurementservice.RMtAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.unre.ucl360.measurementservice.RMtAidlInterface))) {
return ((com.unre.ucl360.measurementservice.RMtAidlInterface)iin);
}
return new com.unre.ucl360.measurementservice.RMtAidlInterface.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
java.lang.String descriptor = DESCRIPTOR;
if (code >= android.os.IBinder.FIRST_CALL_TRANSACTION && code <= android.os.IBinder.LAST_CALL_TRANSACTION) {
data.enforceInterface(descriptor);
}
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(descriptor);
return true;
}
}
switch (code)
{
case TRANSACTION_basicTypes:
{
int _arg0;
_arg0 = data.readInt();
long _arg1;
_arg1 = data.readLong();
boolean _arg2;
_arg2 = (0!=data.readInt());
float _arg3;
_arg3 = data.readFloat();
double _arg4;
_arg4 = data.readDouble();
java.lang.String _arg5;
_arg5 = data.readString();
this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
reply.writeNoException();
break;
}
case TRANSACTION_JRoomMeasurement:
{
java.lang.String _arg0;
_arg0 = data.readString();
java.lang.String _arg1;
_arg1 = data.readString();
java.lang.String _arg2;
_arg2 = data.readString();
java.lang.String _arg3;
_arg3 = data.readString();
java.lang.String _arg4;
_arg4 = data.readString();
java.lang.String _arg5;
_arg5 = data.readString();
boolean _result = this.JRoomMeasurement(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
reply.writeNoException();
reply.writeInt(((_result)?(1):(0)));
break;
}
case TRANSACTION_JRoomMeasurementFactory:
{
java.lang.String _arg0;
_arg0 = data.readString();
java.lang.String _arg1;
_arg1 = data.readString();
java.lang.String _arg2;
_arg2 = data.readString();
java.lang.String _arg3;
_arg3 = data.readString();
java.lang.String _arg4;
_arg4 = data.readString();
boolean _result = this.JRoomMeasurementFactory(_arg0, _arg1, _arg2, _arg3, _arg4);
reply.writeNoException();
reply.writeInt(((_result)?(1):(0)));
break;
}
case TRANSACTION_ParseRoomScene:
{
java.lang.String _arg0;
_arg0 = data.readString();
java.lang.String _arg1;
_arg1 = data.readString();
java.lang.String _arg2;
_arg2 = data.readString();
java.lang.String _arg3;
_arg3 = data.readString();
java.lang.String _arg4;
_arg4 = data.readString();
this.ParseRoomScene(_arg0, _arg1, _arg2, _arg3, _arg4);
reply.writeNoException();
break;
}
case TRANSACTION_RoomMeasurementAndSaveData:
{
java.lang.String _arg0;
_arg0 = data.readString();
boolean _result = this.RoomMeasurementAndSaveData(_arg0);
reply.writeNoException();
reply.writeInt(((_result)?(1):(0)));
break;
}
case TRANSACTION_JRoomMeasurementWithBluePrint:
{
java.lang.String _arg0;
_arg0 = data.readString();
java.lang.String _arg1;
_arg1 = data.readString();
java.lang.String _arg2;
_arg2 = data.readString();
java.lang.String _arg3;
_arg3 = data.readString();
java.lang.String _arg4;
_arg4 = data.readString();
java.lang.String _arg5;
_arg5 = data.readString();
java.lang.String _arg6;
_arg6 = data.readString();
java.lang.String _arg7;
_arg7 = data.readString();
java.lang.String _arg8;
_arg8 = data.readString();
java.lang.String _arg9;
_arg9 = data.readString();
java.lang.String _arg10;
_arg10 = data.readString();
java.lang.String _arg11;
_arg11 = data.readString();
java.lang.String _arg12;
_arg12 = data.readString();
java.lang.String _arg13;
_arg13 = data.readString();
boolean _result = this.JRoomMeasurementWithBluePrint(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11, _arg12, _arg13);
reply.writeNoException();
reply.writeInt(((_result)?(1):(0)));
break;
}
default:
{
return super.onTransact(code, data, reply, flags);
}
}
return true;
}
private static class Proxy implements com.unre.ucl360.measurementservice.RMtAidlInterface
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
@Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(anInt);
_data.writeLong(aLong);
_data.writeInt(((aBoolean)?(1):(0)));
_data.writeFloat(aFloat);
_data.writeDouble(aDouble);
_data.writeString(aString);
boolean _status = mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
/**
* JRoomMeasurement函数中的参数皆为路径:
* scenePath: 点云路径,文件类型为 pts、ptsen
* compass_path: 方位文件路径———— dire.txt
* Ruler_json: 用户设置的测量模式————ruler.json
* cad_path: CAD文件路径
* meshPath: 输出mesh.obj相关文件的路径
* jsonPath:output.json输出路径
*/
// no Blueprint
@Override public boolean JRoomMeasurement(java.lang.String scenePath, java.lang.String compass_path, java.lang.String Ruler_json, java.lang.String cad_path, java.lang.String meshPath, java.lang.String jsonPath) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(scenePath);
_data.writeString(compass_path);
_data.writeString(Ruler_json);
_data.writeString(cad_path);
_data.writeString(meshPath);
_data.writeString(jsonPath);
boolean _status = mRemote.transact(Stub.TRANSACTION_JRoomMeasurement, _data, _reply, 0);
_reply.readException();
_result = (0!=_reply.readInt());
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public boolean JRoomMeasurementFactory(java.lang.String scenePath, java.lang.String compass_path, java.lang.String cad_path, java.lang.String meshPath, java.lang.String jsonPath) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(scenePath);
_data.writeString(compass_path);
_data.writeString(cad_path);
_data.writeString(meshPath);
_data.writeString(jsonPath);
boolean _status = mRemote.transact(Stub.TRANSACTION_JRoomMeasurementFactory, _data, _reply, 0);
_reply.readException();
_result = (0!=_reply.readInt());
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
/**
* The arguements of the API JScanMatch:
* "-d", ------- drawPath
* "-x", ------- xmlPath
* "-s", ------- stage
* "-a", ------- stationId
* "-pm", ------- preMatchPath
* "-im", ------- cadId
* "-is", ------- xmlId
* "-m", ------- resultPath
*/
// Own Blueprint
/**
* The arguements of the API ParseRoomScene
* scene_path, // 点云文件路径
* compass_path, // 方位文件路径
* ruler_json, // 测量规则配置文件
* mesh_path, // 网格输出路径
* contour_xml // 房间轮廓输出路径,输出为XML格式文件
*/
@Override public void ParseRoomScene(java.lang.String scenePath, java.lang.String compass_path, java.lang.String ruler_json, java.lang.String meshPath, java.lang.String contour_xml) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(scenePath);
_data.writeString(compass_path);
_data.writeString(ruler_json);
_data.writeString(meshPath);
_data.writeString(contour_xml);
boolean _status = mRemote.transact(Stub.TRANSACTION_ParseRoomScene, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
@Override public boolean RoomMeasurementAndSaveData(java.lang.String jsonPath) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(jsonPath);
boolean _status = mRemote.transact(Stub.TRANSACTION_RoomMeasurementAndSaveData, _data, _reply, 0);
_reply.readException();
_result = (0!=_reply.readInt());
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public boolean JRoomMeasurementWithBluePrint(java.lang.String scenePath, java.lang.String compass_path, java.lang.String ruler_json, java.lang.String meshPath, java.lang.String contour_xml, java.lang.String drawPath, java.lang.String xmlPath, java.lang.String stage, java.lang.String stationId, java.lang.String preMatchPath, java.lang.String cadId, java.lang.String xmlId, java.lang.String matchResult, java.lang.String jsonPath) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(scenePath);
_data.writeString(compass_path);
_data.writeString(ruler_json);
_data.writeString(meshPath);
_data.writeString(contour_xml);
_data.writeString(drawPath);
_data.writeString(xmlPath);
_data.writeString(stage);
_data.writeString(stationId);
_data.writeString(preMatchPath);
_data.writeString(cadId);
_data.writeString(xmlId);
_data.writeString(matchResult);
_data.writeString(jsonPath);
boolean _status = mRemote.transact(Stub.TRANSACTION_JRoomMeasurementWithBluePrint, _data, _reply, 0);
_reply.readException();
_result = (0!=_reply.readInt());
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_JRoomMeasurement = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_JRoomMeasurementFactory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_ParseRoomScene = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_RoomMeasurementAndSaveData = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
static final int TRANSACTION_JRoomMeasurementWithBluePrint = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
}
public static final java.lang.String DESCRIPTOR = "com.unre.ucl360.measurementservice.RMtAidlInterface";
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;
/**
* JRoomMeasurement函数中的参数皆为路径:
* scenePath: 点云路径,文件类型为 pts、ptsen
* compass_path: 方位文件路径———— dire.txt
* Ruler_json: 用户设置的测量模式————ruler.json
* cad_path: CAD文件路径
* meshPath: 输出mesh.obj相关文件的路径
* jsonPath:output.json输出路径
*/
// no Blueprint
public boolean JRoomMeasurement(java.lang.String scenePath, java.lang.String compass_path, java.lang.String Ruler_json, java.lang.String cad_path, java.lang.String meshPath, java.lang.String jsonPath) throws android.os.RemoteException;
public boolean JRoomMeasurementFactory(java.lang.String scenePath, java.lang.String compass_path, java.lang.String cad_path, java.lang.String meshPath, java.lang.String jsonPath) throws android.os.RemoteException;
/**
* The arguements of the API JScanMatch:
* "-d", ------- drawPath
* "-x", ------- xmlPath
* "-s", ------- stage
* "-a", ------- stationId
* "-pm", ------- preMatchPath
* "-im", ------- cadId
* "-is", ------- xmlId
* "-m", ------- resultPath
*/
// Own Blueprint
/**
* The arguements of the API ParseRoomScene
* scene_path, // 点云文件路径
* compass_path, // 方位文件路径
* ruler_json, // 测量规则配置文件
* mesh_path, // 网格输出路径
* contour_xml // 房间轮廓输出路径,输出为XML格式文件
*/
public void ParseRoomScene(java.lang.String scenePath, java.lang.String compass_path, java.lang.String ruler_json, java.lang.String meshPath, java.lang.String contour_xml) throws android.os.RemoteException;
public boolean RoomMeasurementAndSaveData(java.lang.String jsonPath) throws android.os.RemoteException;
public boolean JRoomMeasurementWithBluePrint(java.lang.String scenePath, java.lang.String compass_path, java.lang.String ruler_json, java.lang.String meshPath, java.lang.String contour_xml, java.lang.String drawPath, java.lang.String xmlPath, java.lang.String stage, java.lang.String stationId, java.lang.String preMatchPath, java.lang.String cadId, java.lang.String xmlId, java.lang.String matchResult, java.lang.String jsonPath) throws android.os.RemoteException;
}