前言:为了通过cmd输入adb命令来执行某些操作,在确保执行完之后再把运行cmd的进程关闭。
为了实现这个功能,我选择通过使用connect绑定lambda表达式进行后台数据的获取,代码如下。
//检测权限是否编辑成功
proExecuteADB->write("echo $?\n");
QString chmoddata;
QStringList chmodqstrl;
QEventLoop chmodloop; //创建一个事件循环,等待进程调用完毕
//绑定进程可以读取通道内容信号,当有可以读取的内容时,readyReadStandardOutput信号被发出
connect(proExecuteADB,&QProcess::readyReadStandardOutput,this,[&chmodloop,&chmoddata,&chmodqstrl,&proExecuteADB,&IfDownloadSuccess]()
{
//读取通道内所有内容
QString slToStr;
chmoddata=QString::fromLocal8Bit(proExecuteADB->readAllStandardOutput());
chmodqstrl<<chmoddata;
slToStr=chmodqstrl.join("");
//判断读取到的内容是否包含特定字符串
if(slToStr.contains("connect failed"))
{
IfDownloadSuccess=false;
proExecuteADB->kill();
chmodloop.quit(); //退出事件循环
}
if(slToStr.count("echo $?", Qt::CaseInsensitive)==1)
{
QString str1=slToStr.mid(slToStr.indexOf("echo $?")+10,1);
if("0"==str1)
{
IfDownloadSuccess=true;
proExecuteADB->kill();
chmodloop.quit(); //退出事件循环
}
}
if(slToStr.count("echo $?", Qt::CaseInsensitive)==2)
{
QString str1=slToStr.mid(slToStr.indexOf("echo $?")+10,1);
QString str2=slToStr.mid(slToStr.indexOf("echo $?",slToStr.indexOf("echo $?")+10)+10,1);
if((str1!="0")&&("0"==str2))
{
IfDownloadSuccess=true;
proExecuteADB->kill();
chmodloop.quit(); //退出事件循环
}
}
});
chmodloop.exec();
connect的作用是在进程已经准备好了读取标准输出时,执行lambda表达式中的代码,首先通过readAllStandardOutput()函数获取读取到的字符串,再加入到字符串队列中,以便整合。
当函数判断获得到的输出结构中有相应的返回值,则杀掉进程并退出loop循环。
一般来说调用完quit()函数之后,程序应该可以执行exec后面的代码,但出于某种我未分析出的原因,程序会再进一次lambda表达式,此时如果执行:chmoddata=QString::fromLocal8Bit(proExecuteADB->readAllStandardOutput());
此时进程已经被清除了,读取通道已关闭,再调用readAllStandardOutput()函数会造成无法读取,导致程序崩溃。之前尝试加了个bool变量来判断是否已经执行过quit()函数,不过在最后一次进入lambda表达式时,bool变量的数值会变得非1非0,而是40之类奇怪的数值。
//给chmoddata赋值会报错,提示无法正常读取
chmoddata=QString::fromLocal8Bit(proExecuteADB->readAllStandardOutput());
chmodqstrl<<chmoddata;
slToStr=chmodqstrl.join("");
解决方法就是在读取信息前加一个判断,判断进程是否存在。不能以进程读输出是否准备就绪为条件:&QProcess::readyReadStandardOutput;因为程序会检测到是可以读取的,但是读不到东西。
//检测权限是否编辑成功
proExecuteADB->write("echo $?\n");
QString chmoddata;
QStringList chmodqstrl;
QEventLoop chmodloop; //创建一个事件循环,等待进程调用完毕
//绑定进程可以读取通道内容信号,当有可以读取的内容时,readyReadStandardOutput信号被发出
connect(proExecuteADB,&QProcess::readyReadStandardOutput,this,[&chmodloop,&chmoddata,&chmodqstrl,&proExecuteADB,&IfDownloadSuccess]()
{
//读取通道内所有内容
QString slToStr;
//增加进程是否存在的判断,如果存在则读取,不存在则继续执行,避免了因为无法读取造成的 程序崩溃问题
if(proExecuteADB!=NULL)
{
chmoddata=QString::fromLocal8Bit(proExecuteADB->readAllStandardOutput());
chmodqstrl<<chmoddata;
slToStr=chmodqstrl.join("");
}
//判断读取到的内容是否包含特定字符串
if(slToStr.contains("connect failed"))
{
IfDownloadSuccess=false;
proExecuteADB->kill();
chmodloop.quit(); //退出事件循环
}
if(slToStr.count("echo $?", Qt::CaseInsensitive)==1)
{
QString str1=slToStr.mid(slToStr.indexOf("echo $?")+10,1);
if("0"==str1)
{
IfDownloadSuccess=true;
proExecuteADB->kill();
chmodloop.quit(); //退出事件循环
}
}
if(slToStr.count("echo $?", Qt::CaseInsensitive)==2)
{
QString str1=slToStr.mid(slToStr.indexOf("echo $?")+10,1);
QString str2=slToStr.mid(slToStr.indexOf("echo $?",slToStr.indexOf("echo $?")+10)+10,1);
if((str1!="0")&&("0"==str2))
{
IfDownloadSuccess=true;
proExecuteADB->kill();
chmodloop.quit(); //退出事件循环
}
}
});
chmodloop.exec();