我有一个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的每个命令都耗时而产生新的过程。
答案 0 :(得分:0)
尝试锁定您的线程。这样可以确保一次仅激活一个进程。
如果另一个线程正忙于执行相同的进程而又调用了一个新线程,则会出现一些冲突。
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();
}