第五章 插件:Android设备插件实现分析
目录
-
插件结构概述 -
插件接口实现分析 -
设备通信机制 -
镜像服务器部署 -
截图功能实现 -
实现特点总结 -
代码优化建议 -
技术要点总结
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")
// ... 接口方法声明
};
核心功能实现:
-
插件基本信息:
-
提供插件名称、版本、图标等元数据 -
返回设备类型为 DeviceType::Android -
设备代理创建:
-
通过 createDeviceProxy()方法创建AndroidDevice实例 -
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', 0, 0).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 命令实现:
-
基本事件映射:将 DeviceEvent枚举映射到对应的 ADB 命令
staticconststd::map<DeviceEvent, QString> eventMap = {
{DeviceEvent::BACK, "input keyevent KEYCODE_BACK"},
{DeviceEvent::HOME, "input keyevent KEYCODE_HOME"},
// ... 其他事件映射
};
-
触摸事件:
-
单点触摸: adb shell input tap x y -
滑动事件: adb shell input swipe x1 y1 x2 y2 duration -
文本输入:
adb shell input text命令
4. 镜像服务器部署
镜像服务器实现是 Android 插件的核心功能之一:
4.1 服务器设置
-
资源推送: -
通过 pushResourceToDevice()将镜像服务器程序推送到设备:
pushResourceToDevice(serial, ":/android/server", "/data/local/tmp/mirror_server")
-
设置执行权限: chmod 755 /data/local/tmp/mirror_server
-
端口转发:
adb -s serial forward tcp:forwardPort tcp:12345
建立本地端口与设备 12345 端口的转发,用于镜像数据流传输。
4.2 服务器启动与监控
-
异步启动:使用 QtConcurrent 异步启动服务器进程,避免阻塞主线程
QtConcurrent::run([=]() {
QStringList args = {"-s", serial, "shell", "/data/local/tmp/mirror_server"};
QProcess process;
process.start("adb", args);
// ...
});
-
状态监控:启动独立线程监控服务器状态,成功启动后发送信号
QtConcurrent::run([=]() {
for (int i = 0; i < 30 && m_running; ++i)
{
// 检查服务器是否启动成功
if (output.contains(":12345"))
{
emit serverStarted(serial);
return;
}
QThread::sleep(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. 实现特点总结
-
多平台支持:针对 Windows 和 MacOS 平台提供了特定的 ADB 路径查找逻辑
-
异步处理:使用 QtConcurrent 实现耗时操作的异步执行,保证 UI 响应性
-
线程安全:通过 QMutex 实现多线程环境下的资源保护
-
健壮性设计:
-
多位置查找 ADB 驱动 -
错误处理和日志输出 -
设备连接状态检查 -
资源管理:使用 Qt 临时文件和自动资源管理机制
7. 代码优化建议
-
错误处理增强:
-
对 ADB 命令失败增加更详细的错误信息和重试机制 -
实现超时控制,避免长时间阻塞 -
缓存机制:
-
缓存设备信息,减少重复查询 -
实现设备状态变化的监听机制 -
内存优化:
-
对大尺寸截图数据实现流式处理 -
优化资源推送过程,避免不必要的文件操作 -
异常恢复:
-
增加镜像服务器异常崩溃的检测和自动重启机制 -
实现设备断开重连处理
8. 技术要点总结
-
插件架构:遵循 Qt 插件标准,通过 Q_INTERFACES 和 Q_PLUGIN_METADATA 实现接口导出 -
ADB 通信:封装 ADB 命令执行,实现与 Android 设备的通信 -
多线程:使用 QtConcurrent 和 QThread 实现异步操作 -
事件处理:实现统一的事件映射机制,支持多种设备操作 -
资源部署:动态将必要资源推送到设备并设置权限
通过以上设计,Android 插件实现了完整的设备发现、信息查询、镜像投屏和远程控制功能,为 ScreenCast 应用提供了 Android 设备支持。
夜雨聆风
