ADB介绍
GitHub: linkedbyte
Android Debug Bridge(ADB)是一种功能强大的命令行工具,它可以让开发者和设备进行通信。ADB 是由三个部分组成:PC上的 adb client、adb server 和设备上的 adb daemon。这三部分构成了一个多连接的设计,即一台PC可以连接多个设备,一台设备也可以连接多个PC。
当启动 adb 客户端时,它会首先检查 adb 服务端进程是否在运行。如果没有运行,它会启动服务端进程。adb 服务端在启动时,会绑定到本地的 TCP 5037 端口,并监听从 adb 客户端发来的命令——所有的 adb 客户端都使用 5037 端口与 adb 服务端通信。
然后,adb 服务端会扫描所有 5555 到 5585 范围内的奇数端口来定位所有的模拟器或设备,并与之建立连接。一旦 adb 服务端找到了 adb daemon(守护进程),它将建立一个到该端口的连接。这样,开发者就可以使用 adb 命令来控制和访问模拟器或设备了。
设备上的 adb daemon 是一个后台进程,它在 Android 设备或模拟器系统中运行。它的作用是连接 adb 服务器,并且为运行在主机上的客户端提供服务。
投屏软件使用到的ADB命令
-
adb devices -l
- 功能:列出当前连接到计算机的所有 Android 设备或模拟器的详细信息。
- 解释:
adb devices
命令用于检查是否有设备或模拟器连接到计算机。添加-l
选项可以提供更详细的信息,例如设备的型号或状态。这对于开发者在调试时确认设备连接非常有用。
-
adb push
- 功能:将计算机上的文件或目录复制到连接的 Android 设备上。
- 解释:使用
adb push
命令,开发者可以将本地计算机上的文件或目录推送到 Android 设备上的指定位置。这对于将测试数据、配置文件或其他资源部署到设备上非常有用。 - 用法:
adb push <本地路径> <设备路径>
-
adb reverse
- 功能:在 Android 设备与计算机之间设置端口转发。
- 解释:
adb reverse
允许开发者将 Android 设备上的某个端口映射到计算机上的端口,从而实现两者之间的通信。这对于在开发过程中需要在设备和计算机之间共享数据或进行调试的应用程序非常有用。 - 用法:
adb reverse <设备端口> <计算机端口>
-
adb shell app_process
- 功能:在 Android 设备的 shell 中以指定权限运行 Java 应用程序。
- 解释:
app_process
是 Android 系统上的一个原生程序,它是 APP 进程的主入口点。通过adb shell
使用app_process
,开发者可以在设备上以特定用户权限(通常是高权限)运行 Java 程序。这对于需要执行系统级操作或测试应用程序在不同权限环境下的行为非常有用。 - 用法:通常涉及更复杂的命令行参数和 Java 类路径设置,但基本形式是在
adb shell
内调用app_process
并传递相应的参数。
使用QProcess执行adb命令
首先,确保你的 Qt 项目包含了必要的头文件,并且链接了相应的 Qt 模块(通常是 core
)。
#include <QCoreApplication>
#include <QProcess>
#include <QDebug>
void runAdbDevices() {
QProcess process;
QString program = "adb";
QStringList arguments;
// 执行 adb devices -l
arguments << "devices" << "-l";
process.start(program, arguments);
process.waitForFinished();
QString output = QString(process.readAllStandardOutput());
qDebug() << "adb devices -l output:" << output;
}
void runAdbPush(const QString &localFilePath, const QString &devicePath) {
QProcess process;
QString program = "adb";
QStringList arguments;
// 执行 adb push
arguments << "push" << localFilePath << devicePath;
process.start(program, arguments);
process.waitForFinished();
QString output = QString(process.readAllStandardOutput());
qDebug() << "adb push output:" << output;
}
void runAdbReverse(int devicePort, int hostPort) {
QProcess process;
QString program = "adb";
QStringList arguments;
// 执行 adb reverse
arguments << "reverse" << QString("tcp:%1").arg(devicePort) << QString("tcp:%2").arg(hostPort);
process.start(program, arguments);
process.waitForFinished();
QString output = QString(process.readAllStandardOutput());
qDebug() << "adb reverse output:" << output;
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
// 调用 adb devices -l
runAdbDevices();
// 调用 adb push,假设你要推送一个名为 "myfile.txt" 的文件到设备的 "/sdcard/" 目录下
runAdbPush("/path/to/myfile.txt", "/sdcard/myfile.txt");
// 调用 adb reverse,假设你要将设备的 8080 端口映射到主机的 8888 端口
runAdbReverse(8080, 8888);
return a.exec();
}
在这段代码中,runAdbDevices
函数执行 adb devices -l
命令,runAdbPush
函数执行 adb push
命令来推送文件,runAdbReverse
函数执行 adb reverse
命令来设置端口转发。每个函数都使用 QProcess
来启动外部程序,并等待其完成。完成后,它们读取并打印命令的输出。
请确保替换 /path/to/myfile.txt
为你要推送的文件的实际路径,并根据需要调整端口号和设备路径。此外,如果你的 adb
不在系统路径中,你需要提供 adb
的完整路径作为 program
变量的值。
使用QProcess异步执行ADB命令
在Qt中,要将QProcess
的执行过程换成异步的,你可以使用信号和槽机制。QProcess
类提供了一系列的信号,如readyReadStandardOutput
、finished
等,这些信号可以在进程输出可用或进程结束时发出。你可以将这些信号连接到自定义的槽函数中以异步地处理进程输出和进程结束事件。
下面是一个修改后的例子,展示了如何使用QProcess
以异步方式执行adb
命令:
#include <QCoreApplication>
#include <QProcess>
#include <QObject>
#include <QDebug>
class AdbProcess : public QObject {
Q_OBJECT
public:
AdbProcess(QObject *parent = nullptr) : QObject(parent) {}
void runAdbCommand(const QString &command) {
adbProcess->start("adb", QStringList() << command);
}
void runAdbDevices() {
runAdbCommand("devices -l");
}
void runAdbPush(const QString &localFile, const QString &remoteDest) {
QStringList args = {"push", localFile, remoteDest};
adbProcess->start("adb", args);
}
void runAdbReverse(int localPort, int remotePort) {
QStringList args = {"reverse", QString("tcp:%1").arg(localPort), QString("tcp:%2").arg(remotePort)};
adbProcess->start("adb", args);
}
private slots:
void onReadyReadStandardOutput() {
QByteArray output = adbProcess->readAllStandardOutput();
qDebug() << "ADB Output:" << output;
}
void onFinished(int exitCode, QProcess::ExitStatus exitStatus) {
qDebug() << "ADB Command Finished"
<< "Exit Code:" << exitCode
<< "Exit Status:" << exitStatus;
adbProcess->deleteLater();
}
private:
QProcess *adbProcess = new QProcess(this);
void setupProcess() {
connect(adbProcess, &QProcess::readyReadStandardOutput, this, &AdbProcess::onReadyReadStandardOutput);
connect(adbProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &AdbProcess::onFinished);
}
public:
// 构造函数中设置进程
AdbProcess(bool setup = true, QObject *parent = nullptr) : QObject(parent) {
if (setup) {
setupProcess();
}
}
};
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
AdbProcess adb;
adb.runAdbDevices();
// 这里可以添加更多的 adb 命令或者其他逻辑
// ...
return a.exec();
}
在这个例子中,AdbProcess
类封装了对 adb
命令的异步调用。构造函数中设置了必要的信号和槽连接。runAdbCommand
方法是一个私有方法,用于启动进程并执行特定的 adb
命令。onReadyReadStandardOutput
和 onFinished
是槽函数,分别用于处理进程的标准输出和进程结束事件。
注意,这里的代码假设你的 adb
命令已经在系统路径中。如果不是,你需要提供 adb
可执行文件的完整路径。
此外,请确保在实际的项目中正确地管理 QProcess
对象的生命周期。在这个示例中,adbProcess
对象在 AdbProcess
类中被创建,并在命令执行完毕后通过 deleteLater
方法进行清理。如果你的应用程序需要在多处执行 adb
命令,你可能需要为每个命令创建一个新的 QProcess
对象,或者确保在命令之间重置 QProcess
对象的状态。
GitHub: linkedbyte
微信:linkedbyte
QQ:2276769057