2

所以对于初学者来说,我有一个相当复杂的系统,它连接到一个 Python Web 套接字来触发一些不同的 Android 事件。我或多或少地认为这个系统在 Mac Mini 上工作。我已经将它移植到 Ubuntu 13.04 并取得了一些成功。我遇到的问题是我用来实际触发这些 Android 事件的两个 python 脚本。

我有两个 .py 文件,run_wsh 和 performAction。本质上,run_wsh 通过套接字连接并告知要触发哪些事件。run_wsh 为 performAction 启动一个子进程,并将输入通过管道传递给 performAction,并将 performAction 的输出返回给 run_wsh。

第一个主要调用是 run_wsh 中的“安装”。run_wsh 将此发送到 performAction,它已经运行了一段时间 True: 循环,等待输入。这可能是问题所在,但我不确定。performAction 通过设置以下内容来读取(使用 python 2 的东西,所以 raw_input 是标准的):

input = raw_input()

performAction 然后通过以下方式检查:

if input is None:
    continue
if input == "Install":
    device.installPackage('pathToMyApk.apk')
    runComponent = 'blah/.activityBlah'
    device.startActivity(component=runComponent)
    time.sleep(1)
    subprocess.call(['blah/adb', 'pull', '/pathToTextFileInAndroid.txt', '/pathToTextFileInUbuntu.txt']
    print "Install Successful"

这是在对确实成功的模拟器的初始 waitForConnection 调用之后。现在,无论何时发送“安装”,它都会挂起而没有任何事情发生。我知道这一点,因为从 run_wsh 脚本中无法读取任何输出。作为参考,以下是来自 run_wsh 的相关位。

args = ['pathToMonkeyRunner', 'pathToPerformAction.py']
prog = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
prog.stdout.readline()
#This is to spit out a printed connection statement for when waitForConnection finishes
...
#Inside install call
inputToWrite = "Install"
prog.stdin.write(inputToWrite)
s = prog.stdout.readline()
f = open('/pathToTextFileInUbuntu.txt', 'r')
t = f.read()
#Read from the file and send information back out through the socket

我之前插入了打印语句来验证 s = prog.stdout.readline() 行是否从未被命中。performAction 中的不同输入还有其他 elif 案例,它们也失败了,但我现在只是在看这个案例。不过,这里真正的问题是,当它挂起时,我最终只是从终端中杀死了 python 进程。当我使用注释掉的安装部分完成此操作时(并且我的 apk 已经通过 adb 手动安装),一旦进程被终止,模拟器最终会像预期的那样拉出活动页面(我正在运行为调试目的打开的窗口,但通常会打开 -no-window)。世界上最奇怪的事情。我已经尝试在代码中插入各种 time.sleep 调用,我想如果我有数据竞争,我可以以一种或另一种方式引导它,但是唉,

拜托,我知道这在大型系统中是一个巨大的问题,但任何帮助都会很棒。我在网上搜索了有关 python、monkey runner 和 Android 的更深入的帮助,但没有特别解决这个问题。

也请忽略代码或我的写作中的任何愚蠢的错别字。我通过盯着 vm 中的终端而不是实际的复制粘贴来复制的代码。我已经将各种路径更改为垃圾,但它们应该足以理解。谢谢!

4

1 回答 1

1

我也对 monkeyrunner 有同样的标准输入问题。(我首先认为这是我的 C# 主机应用程序的问题,但如果我生成了一个本地 python 3 程序,它会毫无问题地读取输入。)

一个不同的答案说 Jython 2.5.3 有一个错误,您可以用 Jython 2.5.4rc1 jar 替换它,但这并没有在 Windows 上为我修复它。


我需要的只是将消息发送到 jython 进程的能力,所以我最终最终运行了一个 HTTP 服务器,而不是 stdin:

import time
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer

class PostHandler(BaseHTTPRequestHandler):
  def do_POST(self):
    content_len = int(self.headers.getheader('content-length', 0))
    post_body = self.rfile.read(content_len)
    for pair in post_body.split(';'):
      x, y = map(int, pair.split(','))
      device.touch(x, y, MonkeyDevice.DOWN_AND_UP)
      time.sleep(0.08)
    
    self.send_response(200)

if __name__ == '__main__':
  print 'Waiting for device connection...'
  device = MonkeyRunner.waitForConnection()

  server = HTTPServer(('localhost', 8080), PostHandler)
  print 'Got device, starting server, use <Ctrl-C> to stop'
  server.serve_forever()
于 2020-11-01T16:18:21.943 回答