Android Monkey Runner 设备调用挂起但在进程被终止时工作 [英] Android Monkey Runner Device Calls Hang but Work when Process Is Killed

查看:26
本文介绍了Android Monkey Runner 设备调用挂起但在进程被终止时工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So for starters, I have a rather complex system that connects to a python web socket to fire off some various Android events. I was more or less given this system in working form on a Mac Mini. I have since ported it to Ubuntu 13.04 with some success. The problem I'm running into is with two python scripts I'm using to actually trigger these Android events.

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

What I have are two .py files, run_wsh and performAction. Essentially run_wsh is connected to via a socket and told what events to fire. run_wsh starts a subprocess for performAction and pipes input to performAction and performAction's output back to run_wsh.

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

The first major call is "Install" in run_wsh. run_wsh sends this down to performAction which has been running in a while True: loop, waiting for input. This may be where the problem lies, but I'm not sure. performAction reads in by setting the following (using python 2 something so raw_input is standard):

input = raw_input()

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

performAction then checks that by the following:

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 中的相关位.

This is after the initial waitForConnection call to the emulator which does succeed. Now whenever "Install" is sent down, it just hangs without anything happening. I know this, because no output can ever be read from the run_wsh script. For reference, below is the relevant bits from 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 调用,我想如果我有数据竞争,我可以以一种或另一种方式引导它,但唉,这似乎也失败了.

I've inserted print statements before to verify that the line, s = prog.stdout.readline(), is never hit. There are other elif cases for different inputs in performAction, which also fail, but I'm just looking at this case for now. The real bugger here though is that when this hangs, I eventually just kill off the python process from the terminal. When I've done this with the install part commented out (and my apk already installed by hand via adb), once the process has been killed, the emulator finally pulls up the activity page like it is supposed to (I'm running with the window open for debugging purposes, but normally would have -no-window on). Strangest thing in the world. I've tried inserting various time.sleep calls into the code thinking perhaps if I have a data race, I can steer it one way or another, but alas, this also seems to have failed.

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

Please, I know this is a huge question in a large system, but any help would be magnificent. I have scoured the web looking for more in depth help with python, monkey runner, and Android with nothing particularly addressing this problem.

另外请忽略代码或我的写作中的任何愚蠢的错别字.我从盯着虚拟机中的终端复制过来的代码,而不是实际的复制粘贴.我已经改变了垃圾的各种路径,但它们应该足以理解.谢谢!

Also please ignore any silly typos in the code or my writing. The code I hand copied over from staring at a terminal in a vm rather than actual copy paste. I've changed the various paths to garbage, but they should be sufficient for understanding. Thanks!

推荐答案

我在使用monkeyrunner 时也遇到了同样的标准输入问题.(我首先认为这是我的 C# 主机应用程序的问题,但如果我改为生成本地 python 3 程序,它将毫无问题地读取输入.)

I had this same stdin problem with monkeyrunner too. (I first thought it was a problem with my C# host app, but if I instead spawned a local python 3 program it would read input without problems.)

A 不同的答案表示 Jython 2.5.3 存在错误,您可以将其替换为 Jython 2.5.4rc1jar,但这并没有为我在 Windows 上修复它.

A different answer says there's a bug with Jython 2.5.3 and you can replace that with the Jython 2.5.4rc1 jar, but that didn't fix it for me on Windows.

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

What I needed was only the ability to send messages to the jython process, so instead of stdin I ultimately ended up running an HTTP server:

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()

这篇关于Android Monkey Runner 设备调用挂起但在进程被终止时工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆