2607C++,soui与安卓

原文

SOUI安卓:一套C++代码,实现真正的跨平台``UI

这里介绍SOUI框架的安卓适配方案,展示如何用C++开发高性能,安全,跨平台移动应用,同时与安卓``本地系统无缝整合.

为什么选择SOUI安卓?

移动开发领域,跨平台方案层出不穷,但真正能完成"一套代码全平台运行"的寥寥无几.SOUI安卓方案凭借其独特的设计理念,为你带来了全新的选择.

核心优势

特性 说明
零改动跨平台 基于Win32,API仿真层,窗口C++业务代码几乎零改动即可运行在安卓
单一UI线程 C++Java共享安卓``主线程,无需跨线程分发,JNI调用零延迟
本地无缝整合 AndroidView系统深度混合,可与本地控件混合布局
C++``高性能 编译型语言,运行效率远超解释型语言,适合复杂计算场景
代码安全 本地代码编译,反编译难度极高,保护核心逻辑
无方法数限制 不受Android64K方法数限制,项目规模无上限
全平台规划 桌面端Windows,Linux,Macos全兼容,移动端安卓首发,后续支持iOS,真正实现一套代码跑遍全平台

架构设计:Win32模拟层方案

SOUI安卓的核心设计理念是:在安卓之上模拟一整套Win32``子系统.

cpp 复制代码
┌------------------┐
│                    业务层(C++ SHostWnd 子类)                    │
│  CMainDlg::OnInitDialog / OnButtonClick / OnTimer / OnClose     │
└--------┬------------┘
                       │ SendMessage / SetTimer / InvalidateRect
                       ▼
┌------------------┐
│              SOUI 框架(SWindow 树 / RenderTarget)               │
│                   <- Skia 后端 Win/Android 共享                   │
└-------┬-------------┘
                       │ ::CreateWindowEx / ::SetCapture / ::ShowWindow
                       ▼
┌------------------┐
│              swinx(`跨平台` Win32 API 仿真层)                      │
│   WndMgr::fromHwnd(nativeId) -> WndObj -> AndroidPlatformAPI      │
└-------┬-------------┘
                       │ JNI 桥接调用
                       ▼
┌------------------┐
│           Android Java 层(View / Handler / Clipboard)           │
│  SouiScreen / SouiSurface / SouiPlatformBridge / NativeEditView │
└------------------┘

三层架构详解

1,C++Native层:你的业务代码,基于Win32,API编写,与窗口完全一致

2,JNI桥接层:实现C++Java双向通信,所有方法ID在初化时一次缓存

3,JavaUI层:安卓本地视图系统,保存SOUI窗口的渲染和交互

单一UI线程:SOUI的核心设计优势

SOUI安卓的一个革命性设计策略:C++业务代码完全运行在安卓``主线程,不创建独立的渲染线程工作线程.

这与主流跨平台方案构成鲜明对比:

线程模型对比

方案 线程模型 复杂度
SOUI安卓 C+++Java共享主线程 最简单
Flutter UI线程+Raster线程+IO线程 复杂
Qt QtThread+RenderThread 中等

单一UI线程的三大好处

1.JNI调用零延迟,无需跨线程分发

cpp 复制代码
//`SouiPlatformBridge.cpp`直接在`主线程`调用`Java`方法
jboolean result = env->CallBooleanMethod(m_javaBridge, m_clipboardSetDataMethod, (jint)uFormat, jText);

因为C++Java运行在同一线程:

1,无需Handler.post/runOnUiThread:直接调用``Java方法,零切换线程成本

2,无需PlatformChannel:不像Flutter需要异步消息队列传递数据

3,无需Future/Promise:同步调用,代码更直观,调试更简单

2.View操作直接同步,避免条件竞争

cpp 复制代码
//直接操作`视图`,无需线安顾虑
env->CallVoidMethod((jobject)hWnd, midShow, SW_SHOW);
env->CallVoidMethod((jobject)hWnd, midMoveWindow, x, y, width, height);

FlutterQt中,你需要:

Flutter:PlatformChannel``发送消息,等待回调

Qt:使用QMetaObject::invokeMethod或信号槽机制

这些机制不仅增加了代码复杂度,还引入了条件竞争和延迟.

3.生命期天然对齐,管理内存简单

cpp 复制代码
@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
//`直接调用``C++`启动函数,无需同步线程
    mSouiMainHwnd = SouiPlatformBridge.getInstance().souiStartup(mScreenId, getSurfaceHwnd(), mSouiLayout);
}
@Override
protected void onDetachedFromWindow() {
//`直接调用``C++``析构器`,资源立即释放
    SouiPlatformBridge.getInstance().souiShutdown(mScreenId);
    super.onDetachedFromWindow();
}

因为所有代码在同一线程执行:

1,无生命期同步问题:活动析构时立即析构``C++资源

2,无泄漏内存风险:无需担心线程间资源引用导致的泄漏

3,无悬垂指针问题:C++指针和Java对象生命期一致

性能对比:单一线程vs``多线程

cpp 复制代码
┌-----------------┐
│                   用户操作(点击按钮)                         │
└---------┬----------┘
                               │
        ┌-------┼-------┐
        ▼                      ▼                      ▼
┌------┐    ┌-----┐    ┌-----┐
│  SOUI for     │    │    Flutter      │    │      Qt         │
│   Android     │    │                 │    │                 │
│               │    │                 │    │                 │
│ C++ 处理      │    │ Dart 处理       │    │ C++ 处理        │
│ (`主线程`)      │    │ (UI 线程)       │    │ (QtThread)      │
│               │    │                 │    │                 │
│ JNI 调用      │    │ Platform        │    │ QMetaObject     │
│ (`主线程`)      │    │ Channel         │    │ ::invokeMethod  │
│               │    │ (异步消息)      │    │ (`跨线程`)        │
│               │    │                 │    │                 │
│ Java View     │    │ Android         │    │ Java View       │
│ 更新(`主线程`)  │    │ View 更新       │    │ 更新            │
│               │    │ (平台线程)      │    │                 │
└------┘    └-----┘    └-----┘
        │                      │                      │
        ▼                      ▼                      ▼
   ~0ms 延迟              ~16ms+ 延迟            ~8ms+ 延迟

SOUI的单一线程模型避免了切换线程的成本,响应速度更快,代码更简单.

无缝本地整合:与安卓系统深度混合

SOUI安卓不是一个独立的渲染引擎,而是与安卓``本地系统``深度混合的方案.

本地控件作为SOUI``子窗口

cpp 复制代码
//注册本地`视图`工厂
SouiPlatformBridge.registerViewFactory("edit", NativeEditView::new);

registerViewFactory,可按SOUI的子控件使用安卓本地控件(如EditText或Button),享受本地控件的所有特性(如输入法支持,无障碍支持等).

SOUI嵌入本地布局

xml 复制代码
<!-- activity_xml_host.xml -->
<LinearLayout ...>
    <androidx.appcompat.widget.Toolbar ... />
    <com.soui.SouiScreen
        app:screenId="0x0000_D001"
        app:souiLayout="layout:dlg_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton ... />
</LinearLayout>

SOUISouiScreen可按普通AndroidView嵌入任意本地布局,与Toolbar,FloatingActionButton本地控件共存.

生命期完美对齐

cpp 复制代码
@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    if (mScreenId != 0L) {
        mSouiMainHwnd = SouiPlatformBridge.getInstance().souiStartup(mScreenId, getSurfaceHwnd(), mSouiLayout);
    }
}
@Override
protected void onDetachedFromWindow() {
    SouiPlatformBridge.getInstance().souiShutdown(mScreenId);
    super.onDetachedFromWindow();
}

SOUI``窗口系统生命期AndroidActivity完美对齐,onAttachedToWindow时启动,onDetachedFromWindow时析构,避免泄漏内存.

C++``高性能:超越本地的运行效率

编译型语言优势

1,C++作为编译型语言,相比解释型语言(如Java,Kotlin,Dart)有明显的性能优势:

2,立即执行:按本地代码编译代码,无需运行时解释

3,内存控制:手动管理内存,避免GC停顿

4,SIMD优化:支持NEON/AArch64/SSSE3SIMD指令,大幅提升计算密集型任务性能

代码安全:反编译难度极高

本地代码保护

1,按.so``动态库编译C++代码,相比Java/Kotlin代码有更高的安全性:

2,无源暴露:即使反编译也只能得到汇编代码,难以恢复业务逻辑

3,混淆支持:可使用ProGuard+LLVM混淆进一步增加逆向难度

4,加密支持:支持加密保护.so文件

64K方法数限制

1,安卓平台对单个DEX文件有65536个方法的限制,这对大型项是一个严重的瓶颈.使用C++开发:

2,方法数零压力:C++代码不占用DEX方法数

3,项目规模无上限:可无限扩展业务代码,无需担心方法数超限

Activity/多屏幕支持

screenId机制,SOUI安卓支持在多个活动中独立保存不同SOUI``窗口系统.

cpp 复制代码
//`DefaultHostActivity.java`
public class DefaultHostActivity extends AppCompatActivity {
    private static final long SCREEN_ID = 0x0000_D001L;
    private static final String LAYOUT_DEMO = "layout:dlg_main";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SouiScreen mScreen = new SouiScreen(this,SCREEN_ID,LAYOUT_DEMO);
        setContentView(mScreen);
    }
}

每个活动拥有独立的screenId,窗口系统互不干扰,支持多任务场景.

完整功能支持

处理输入事件

1,触摸事件->Win32``鼠标消息(WM_LBUTTONDOWN/UP/MOUSEMOVE)

2,双击检测->WM_LBUTTONDBLCLK

3,右键菜单->WM_RBUTTONDOWN

4,滚轮事件->WM_MOUSEWHEEL/WM_MOUSEHWHEEL

5,键盘事件->WM_KEYDOWN/WM_SYSKEYDOWN

6,SetCapture/ReleaseCapture``完全对齐``Win32语义

窗口管理

1,CreateWindowEx/DestroyWindow

2,MoveWindow/SetWindowPos

3,ShowWindow/UpdateWindow

HWND_MESSAGE消息占位窗口

计时器

1,SetTimer/KillTimer,完全对齐``Win32语义

2,支持非窗口``计时器(hWnd==0)

3,支持回调函数(TIMERPROC)

剪切板

1,clipboardOpen/clipboardClose

2,clipboardGetData/clipboardSetData

3,clipboardEmpty/clipboardIsFormatAvailable

IME输入

1,软键盘弹/保存监听

2,键盘高度同步

3,输入连接管理

4,光标位置查询(EM_GETSEL)

与其他跨平台方案对比

特性 SOUI安卓 Flutter Qt
语言 C++ Dart C++/QML
渲染方式 AndroidView+Skia 自绘引擎+`Skia QPA+OpenGL`
线程模型 单一线程(C+++Java共享主线程) 多线程(UI+Raster+IO) 多线程(QtThread+RenderThread)
线程复杂度 最简单 复杂 中等
JNI调用延迟 ~0ms(同步调用) ~16ms+(PlatformChannel) ~8ms+(跨线程分发)
本地整合 无缝 PlatformChannel JNI
性能
代码安全
方法数限制 有限
开发效率 需要C++技能
热重载 (QML)

开发环境要求

组件 版本要求
AndroidStudio Hedgehog(2023.1)及以上
AndroidSDK compileSdk34,minSdk28
AndroidNDK 21.x/25.x/26.x
CMake >=3.18.1
JDK 17

快速开始

1.克隆代码

cpp 复制代码
git clone https://github.com/soui4/soui.git soui4
cd soui4
git submodule update -init -recursive

2.打开项

使用AndroidStudio打开demos/androiddemo目录,GradleSync自动下载依赖并配置CMake.

3.编译运行

调试构建:./gradlew.batassembleDebug

运行:点击运行按钮,选择安卓设备或模拟器

未来规划

SOUI安卓只是SOUI移动端适配的第一步,期望将很快实现IOS支持,到时候真正实现一套C++代码,全平台运行.

适合场景

场景 是否适合
已有大量SOUI(Windows)C++业务代码,需要低成本上Android 强烈推荐
需要高性能,代码安全的移动应用 推荐
跨平台需求:Windows+Android+iOS 推荐(未来支持iOS)
新团队,新项,追求开发效率 不推荐(建议Flutter)
需要大量动效,手势交互 不推荐(建议Flutter/本地)

参考

1,SOUI4官方仓库(https://gitee.com/setoutsoft/soui4),这里

2,SOUI安卓技术文档,这里

3,SOUIAndroidvsFluttervsQt对比,这里

相关推荐
fqbqrr5 小时前
2607C++,使用微软detours勾挂工具
c++
蓝悦无人机8 小时前
C++基础 — 函数总结
开发语言·c++
我不是懒洋洋10 小时前
从零实现一个分布式监控:Prometheus的核心设计
c++
An_s10 小时前
c++对接pdfium(一)win系统篇
开发语言·c++
众少成多积小致巨10 小时前
C++ 规范参考(上)
c++
一拳一个呆瓜14 小时前
【STL】iostream 编程:使用提取运算符
c++·stl
我不是懒洋洋15 小时前
从零实现一个分布式日志平台:ELK的核心设计
c++
c2385615 小时前
下篇:回溯与剪枝的「智慧寻宝人」——DFS 进阶与网格 / 图论应用
c++·深度优先·图论·剪枝
神仙别闹15 小时前
基于QT(C++)实现Windows 自启动项查看和分析
c++·windows·qt