我有一个Unity应用程序,它创建一个尝试通过adb shell向Android设备发送命令的进程。我可以在应用程序的过程中发送命令。但我第一次只收到Android设备的输出。我不知道它是否与OutputDataReceived有缓冲问题。输入通过但我在Unity编辑器上没有收到任何日志。如果我将Process.StartInfo.CreateNoWindow变为true,我可以看到在Unity外部生成的adb shell中的所有输出。首次执行后,输出不会从该控制台重定向到Unity。
public void StartShellProcessAsync ()
{
ShellThread = new Thread(() =>
{
ShellProcess = new Process();
ShellProcess.StartInfo.FileName = "adb.exe";
ShellProcess.StartInfo.Arguments = "shell";
ShellProcess.StartInfo.CreateNoWindow = false;
ShellProcess.StartInfo.UseShellExecute = false;
ShellProcess.StartInfo.RedirectStandardOutput = true;
ShellProcess.StartInfo.RedirectStandardError = true;
ShellProcess.StartInfo.RedirectStandardInput = true;
ShellProcess.EnableRaisingEvents = true;
ShellProcess.OutputDataReceived += new DataReceivedEventHandler(OnOutputDataReceived);
ShellProcess.ErrorDataReceived += new DataReceivedEventHandler(OnErrorDataReceived);
ShellProcess.Exited += new EventHandler(OnProcessExited);
ShellProcess.Start();
ShellProcess.BeginOutputReadLine();
ShellProcess.BeginErrorReadLine();
ShellProcess.WaitForExit();
});
ShellThread.Start();
}
我在Unity中有按钮发送如下命令:
am start -m <application activity>
am stack list
我试图读取am stack list
的输出它是否有效,如果它是我发出的第一个命令。但是如果我在am start -m <application activity>
之后运行它,输出就不会通过Unity了。
我在一个线程中运行ShellProcess的原因是让整个应用程序执行过程保持打开状态。我不想为我发送到Android的每个命令生成一个新进程,因为它很耗时。
尝试锁定你的线程。这可确保一次只有一个进程处于活动状态。
如果在另一个线程忙于执行相同的过程时调用新线程,则会发生一些冲突。
private readonly object balanceLock = new object();
//Place this code elsewhere
private void Instantiate_Shell_Once()
{
ShellProcess = new Process();
ShellProcess.StartInfo.FileName = "adb.exe";
ShellProcess.StartInfo.Arguments = "shell";
ShellProcess.StartInfo.CreateNoWindow = false;
ShellProcess.StartInfo.UseShellExecute = false;
ShellProcess.StartInfo.RedirectStandardOutput = true;
ShellProcess.StartInfo.RedirectStandardError = true;
ShellProcess.StartInfo.RedirectStandardInput = true;
ShellProcess.EnableRaisingEvents = true;
ShellProcess.OutputDataReceived += new DataReceivedEventHandler(OnOutputDataReceived);
ShellProcess.ErrorDataReceived += new DataReceivedEventHandler(OnErrorDataReceived);
ShellProcess.Exited += new EventHandler(OnProcessExited);
}
public void StartShellProcessAsync ()
{
ShellThread = new Thread(() =>
{
lock(balanceLock)
{
ShellProcess.Start();
ShellProcess.BeginOutputReadLine();
ShellProcess.BeginErrorReadLine();
ShellProcess.WaitForExit();
}
});
ShellThread.Start();
}