DuiLib跨平台(二) -- 安卓篇

在上一篇中,我们成功地将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 在移动端焕发新生!