在上一篇中,我们成功地将DuiLib界面库移植到了 Linux 和 macOS 桌面平台,并且已经跑通了一个简单的Demo。这一次,我们把目标进一步推进到移动端:让 DuiLib 运行在 Android 系统上。
一、环境安装
我是在win10电脑+MuMu模拟器测试的。
1,安装Android Studio,NDK, CMake。
2,配置环境变量。


如果已经有cmake的路径了,删了,用这个。
3,安装一个安卓模拟器,比如MuMu、雷电等等。把虚拟机的ADB调试,ROOT权限打开(仅仅是为了ES文件浏览器查看文件)。也可以使用Android Studio下载的虚拟机,或者干脆用真机测试。
二、编译
我建议在跨平台代码中,也应该使用SDL3动态库,SDL3处理地很好,不需要太担心在别的设备缺少链接库的事情。
1,获取源码
git clone https://github.com/xfcanyue/DuiLib_DuiEditor.git
2, 编译SDL3
进入3rd目录
运行bat文件,makeSDL_android.bat x86_64,当前编译x86_64的so。
bat支持的参数有
arm64-v8a - 64-bit ARM
armeabi-v7a - 32-bit ARM
x86 - 32-bit
x86x86_64 - 64-bit x86
等CMD窗口跑完,编译结果在build_android_x86_64文件夹中。
3, 编译SDL_ttf
同样的,
进入3rd目录,
运行bat文件,makeSDL_ttf_android.bat x86_64。
3,编译DuiLib
进入DuiLib目录
运行bat文件,makeDuiLib_android x86_64。
不出意外,已经编译成功了。如果需要arm64的库,比如你是用真机测试的,使用参数"arm64-v8a"再跑一遍就行了。
三、编写Demo
这一节,我们开始详细地图文介绍,如何从零构造一个DuiLib Android项目。
1,打开Android Studio,New Project,选择Native C++。

2,红框中的内容要改一下

修改完成,下一步,完成。
3, 默认的工程应该是这样的,感觉要修改无数个地方,不着急,慢慢来。。

4,修改CMakeLists.txt。
直接去Android/duidemo拷贝一个过来。
5,这些基础文件都从duidemo复制一份过来。
把duidemo里面的App.h、App.cpp、MainFrame.h、MainFrame.cpp拷贝到cpp目录。
assets整个文件夹也拷贝过来,放到main目录下。
main/java 里面的com目录删除,相应的去duidemo里面的org拷贝过来。
jniLibs目录复制过来,把刚才编译好的libSDL3.so、libSDL3_ttf.so,libDuiLib.so放到对应的平台下面。
6,修改AndroidManifest.xml
XML
<activity
android:name="org.libsdl.app.SDLActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
把 android:name=".MainActivity" 改成 android:name="org.libsdl.app.SDLActivity",姑且把这个当成安卓应用的入口点吧。
7,打开app/build.gradle,把cmake版本号改成你当前用的,比如4.1.2。
8,删除默认的native-lib.cpp,或者直接改文件名为main.cpp,在main.cpp粘贴这段代码:
cpp
#include "App.h"
using namespace DuiLib;
extern "C" int SDL_main(int argc, char* argv[])
{
//设置主窗口的名字
uiApp.SetAppName(_T("Test"));
uiApp.SetResType_File(_T("skin"));
CPaintManagerUI::SetResourcePath("skin");
CPaintManagerUI::SetRenderEngineType(DuiLib_Render_Sdl);
//初始化duilib, 注册插件,创建主窗口
if (!uiApp.InitInstance(argc, argv))
return 0;
//进入消息循环
uiApp.Run();
//清理资源。
uiApp.ExitInstance();
return 0;
}
其实不改文件名也行,但这不符合我们的习惯。
安卓应用是基于Java语言的,本身并没有像main这样的入口函数。
SDL_main实际上是动态库导出的一个函数。
对了,我们是在写一个动态库。
程序运行时,Java导入我们的库libMain.so,然后调用SDL_main。flutter差不多也是这个模式,总之一定是通过Java启动。。
和MacOS App一样,也需要重写CApp::InitResource(),并且在main函数中设定资源路径,启动时会自动从assets读取。
9,打开安卓模拟器,记得开启ADB调试。
进入 E:\AndroidSDK\platform-tools,具体目录根据你安装时候的选择。
在cmd中运行:adb.exe connect 127.0.0.1:7555
10,回到Android Studio, 点击菜单 -- 文件 -- Sync Project width Gradle Files。
这个操作会把刚才在windows资源管理器中增加修改删除的文件,同步到项目中。
11,点击 Android Studio顶部工具栏的绿色小三角开始编译,注意一下是否已连接模拟器。

左边是当前连接的设备。
臭虫按钮是进入debug模式。
12,如果一切正常,我们就成功地在安卓上打开了一个奇怪的窗口。

13,研究一下.apk
在cmd中运行
bash
E:\AndroidSDK\platform-tools>adb shell pm path com.example.duitest
package:/data/app/~~DYW9JEEfZHU_tp79MiSMgw==/com.example.duitest-S_Wdzszfm-qd98POW221Gw==/base.apk
可以看到app的安装路径,把base.apk搞出来,弄到windows系统里面。

这是一个zip文件,lib里面包含了我们的库,assets里面是skin文件夹。
四、结语
通过本篇,我们完成了 DuiLib 在 Android 平台上的移植。
下一次,我们将探索 iOS 移植。
代码仓库 :GitHub - xfcanyue/DuiLib_DuiEditor: UIDesigner for duilib · GitHub
欢迎各位开发者一同参与,让 DuiLib 在移动端焕发新生!