乐于分享
好东西不私藏

第五章 插件:Android设备插件实现分析

本文最后更新于2026-01-02,某些文章具有时效性,若有错误或已失效,请在下方留言或联系老夜

第五章 插件:Android设备插件实现分析

目录

  1. 插件结构概述
  2. 插件接口实现分析
  3. 设备通信机制
  4. 镜像服务器部署
  5. 截图功能实现
  6. 实现特点总结
  7. 代码优化建议
  8. 技术要点总结

1. 插件结构概述

Android 设备插件由两个主要类组成:

  • AndroidDevicePlugin:实现 IDevicePlugin 接口,负责插件注册、基本信息提供和设备代理创建
  • AndroidDevice:实现 DeviceProxy 接口,负责与 Android 设备的实际通信和控制

2. 插件接口实现分析

2.1 AndroidDevicePlugin 类

AndroidDevicePlugin 是标准的 Qt 插件类,继承自 QObject 和 IDevicePlugin 接口:

classAndroidDevicePlugin :public QObject, public IDevicePlugin
{
Q_OBJECT
Q_INTERFACES(IDevicePlugin)
Q_PLUGIN_METADATA(IID "IDevicePlugin")

// ... 接口方法声明
}
;

核心功能实现:

  1. 插件基本信息

    • 提供插件名称、版本、图标等元数据
    • 返回设备类型为 DeviceType::Android
  2. 设备代理创建

    • 通过 createDeviceProxy() 方法创建 AndroidDevice 实例
  3. ADB 驱动管理

    • 环境变量 ANDROID_HOME 目录
    • 系统 PATH 环境变量
    • 应用程序目录
    • 特定平台默认路径(Windows/Mac)
    • checkDriverAvailable() 检查 ADB 驱动是否可用
    • getDriverPath() 在多个位置查找 ADB 可执行文件:

2.2 AndroidDevice 类

AndroidDevice 实现 DeviceProxy 接口,是实际处理与 Android 设备通信的核心类:

classAndroidDevice :public DeviceProxy
{
    Q_OBJECT

public:
// 设备信息查询方法
QVector<DeviceInfo> listDevices()override;
QString deviceModel(const QString& serial)override;
// ... 其他设备信息方法

// 镜像服务器管理
boolsetupMirrorServer(const QString& serial, int forwardPort)override;
boolstartMirrorServer(const QString& serial)override;
boolstopMirrorServer(const QString& serial)override;

// 事件发送
boolsendEvent(const DeviceInfo& dev, DeviceEvent eventType)override;
boolsendTouchEvent(const DeviceInfo& dev, QPoint pos)override;
// ... 其他事件方法

// 截图功能
boolscreenshot(const QString& serial, QByteArray& imageData)override;

// ... 其他方法
private:
boolpushResourceToDevice(const QString& serial, const QString& resourcePath, const QString& devicePath);
bool m_running = false;
    QMutex m_mutex;
};

3. 设备通信机制

Android 插件通过 ADB (Android Debug Bridge) 与设备通信,所有操作都通过执行 ADB 命令实现:

3.1 设备发现与列表获取

QVector<DeviceInfo> AndroidDevice::listDevices()
{
    QVector<DeviceInfo> devices;
    QString output;
if (!Shell::executeCommandQuiet("adb", {"devices"}, &output))
    {
return devices;
    }

    QStringList lines = output.split('\n', Qt::SkipEmptyParts);
for (const QString& line : lines)
    {
if (line.contains("\tdevice"))
        {
            QString serial = line.section('\t'00).trimmed();
            DeviceInfo info;
            info.type = DeviceType::Android;
            info.serial = serial;
            devices.append(info);
        }
    }
return devices;
}

通过执行 adb devices 命令获取已连接设备列表,并解析输出提取设备序列号。

3.2 设备信息查询

插件实现了多种设备信息查询方法:

  • deviceModel(): 通过 adb shell getprop ro.product.model 获取设备型号
  • deviceResolution(): 通过 adb shell wm size 获取设备分辨率
  • deviceRotation(): 通过 adb shell dumpsys window displays 获取屏幕旋转角度
  • queryDeviceInfo(): 综合调用上述方法,构建完整的设备信息

3.3 事件发送机制

事件发送基于 Android 的 input 命令实现:

  1. 基本事件映射:将 DeviceEvent 枚举映射到对应的 ADB 命令
staticconststd::map<DeviceEvent, QString> eventMap = {
    {DeviceEvent::BACK, "input keyevent KEYCODE_BACK"},
    {DeviceEvent::HOME, "input keyevent KEYCODE_HOME"},
// ... 其他事件映射
};
  1. 触摸事件

    • 单点触摸:adb shell input tap x y
    • 滑动事件:adb shell input swipe x1 y1 x2 y2 duration
  2. 文本输入adb shell input text 命令

4. 镜像服务器部署

镜像服务器实现是 Android 插件的核心功能之一:

4.1 服务器设置

  1. 资源推送
    • 通过 pushResourceToDevice() 将镜像服务器程序推送到设备:
     pushResourceToDevice(serial, ":/android/server""/data/local/tmp/mirror_server")
  • 设置执行权限:chmod 755 /data/local/tmp/mirror_server
  1. 端口转发
   adb -s serial forward tcp:forwardPort tcp:12345

建立本地端口与设备 12345 端口的转发,用于镜像数据流传输。

4.2 服务器启动与监控

  1. 异步启动:使用 QtConcurrent 异步启动服务器进程,避免阻塞主线程
   QtConcurrent::run([=]() {
       QStringList args = {"-s", serial, "shell""/data/local/tmp/mirror_server"};
       QProcess process;
       process.start("adb", args);
// ...
   });
  1. 状态监控:启动独立线程监控服务器状态,成功启动后发送信号
   QtConcurrent::run([=]() {
for (int i = 0; i < 30 && m_running; ++i)
       {
// 检查服务器是否启动成功
if (output.contains(":12345"))
           {
               emit serverStarted(serial);
return;
           }
           QThread::sleep(1);
       }
   });
  1. 线程安全:使用 QMutex 保护共享状态,确保多线程操作安全

5. 截图功能实现

截图功能通过 screencap 命令实现:

boolAndroidDevice::screenshot(const QString& serial, QByteArray& imageData)
{
if (!Shell::executeCommand("adb", {"-s", serial, "exec-out""screencap""-p"}, &imageData))
    {
        qWarning() << "Failed to execute screencap command";
returnfalse;
    }
returntrue;
}

使用 exec-out 选项直接将输出流重定向到程序内存,避免创建临时文件,提高效率。

6. 实现特点总结

  1. 多平台支持:针对 Windows 和 MacOS 平台提供了特定的 ADB 路径查找逻辑

  2. 异步处理:使用 QtConcurrent 实现耗时操作的异步执行,保证 UI 响应性

  3. 线程安全:通过 QMutex 实现多线程环境下的资源保护

  4. 健壮性设计

    • 多位置查找 ADB 驱动
    • 错误处理和日志输出
    • 设备连接状态检查
  5. 资源管理:使用 Qt 临时文件和自动资源管理机制

7. 代码优化建议

  1. 错误处理增强

    • 对 ADB 命令失败增加更详细的错误信息和重试机制
    • 实现超时控制,避免长时间阻塞
  2. 缓存机制

    • 缓存设备信息,减少重复查询
    • 实现设备状态变化的监听机制
  3. 内存优化

    • 对大尺寸截图数据实现流式处理
    • 优化资源推送过程,避免不必要的文件操作
  4. 异常恢复

    • 增加镜像服务器异常崩溃的检测和自动重启机制
    • 实现设备断开重连处理

8. 技术要点总结

  • 插件架构:遵循 Qt 插件标准,通过 Q_INTERFACES 和 Q_PLUGIN_METADATA 实现接口导出
  • ADB 通信:封装 ADB 命令执行,实现与 Android 设备的通信
  • 多线程:使用 QtConcurrent 和 QThread 实现异步操作
  • 事件处理:实现统一的事件映射机制,支持多种设备操作
  • 资源部署:动态将必要资源推送到设备并设置权限

通过以上设计,Android 插件实现了完整的设备发现、信息查询、镜像投屏和远程控制功能,为 ScreenCast 应用提供了 Android 设备支持。

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » 第五章 插件:Android设备插件实现分析
×
订阅图标按钮