2012-08-31 3 views
6

MonkeyRunner를 사용하여, 모든 너무 자주 같은 오류 얻을 : 내가 읽은 바로는MonkeyRunner에서 SocketExceptions를 잡는 방법은 무엇입니까?

120830 18:39:32.755:S [MainThread] [com.android.chimpchat.adb.AdbChimpDevice] Unable to get variable: display.density 
120830 18:39:32.755:S [MainThread] [com.android.chimpchat.adb.AdbChimpDevice]java.net.SocketException: Connection reset 

을, 때로는 ADB 연결이 나쁜 간다, 당신은 다시 연결해야합니다. 유일한 문제는 SocketException을 잡지 못합니다. 내 코드를 다음과 같이 포장합니다.

try: 
    density = self.device.getProperty('display.density') 
except: 
    print 'This will never print.' 

그러나 예외는 분명히 발신자에게 제기되지 않은 것 같습니다.

>>> from java.io import FileInputStream 
>>> def test_java_exceptions(): 
...  try: 
...   FileInputStream('bad mojo') 
...  except: 
...   print 'Caught it!' 
... 
>>> test_java_exceptions() 
Caught it! 

가 어떻게 이러한 소켓 예외를 처리 할 수 ​​있습니다 나는 MonkeyRunner/자이 썬은 내가 기대했던 방법을 자바 예외를 잡을 수 있다는 것을 확인했습니다?

답변

2

다음은 사용이 끝난 해결 방법입니다. ADB 장애로부터 고통을 수있는 모든 기능은 바로 다음 장식 사용해야합니다 :이 새 연결을 만들 수 있기 때문에

from subprocess import call, PIPE, Popen 
from time import sleep 

def check_connection(f): 
    """ 
    adb is unstable and cannot be trusted. When there's a problem, a 
    SocketException will be thrown, but caught internally by MonkeyRunner 
    and simply logged. As a hacky solution, this checks if the stderr log 
    grows after f is called (a false positive isn't going to cause any harm). 
    If so, the connection will be repaired and the decorated function/method 
    will be called again. 

    Make sure that stderr is redirected at the command line to the file 
    specified by config.STDERR. Also, this decorator will only work for 
    functions/methods that take a Device object as the first argument. 
    """ 
    def wrapper(*args, **kwargs): 
     while True: 
      cmd = "wc -l %s | awk '{print $1}'" % config.STDERR 
      p = Popen(cmd, shell=True, stdout=PIPE) 
      (line_count_pre, stderr) = p.communicate() 
      line_count_pre = line_count_pre.strip() 

      f(*args, **kwargs) 

      p = Popen(cmd, shell=True, stdout=PIPE) 
      (line_count_post, stderr) = p.communicate() 
      line_count_post = line_count_post.strip() 

      if line_count_pre == line_count_post: 
       # the connection was fine 
       break 
      print 'Connection error. Restarting adb...' 
      sleep(1) 
      call('adb kill-server', shell=True) 
      call('adb start-server', shell=True) 
      args[0].connection = MonkeyRunner.waitForConnection() 

    return wrapper 

을, 당신은 변경 될 수 있도록 장치 개체의 현재 연결을 포장해야합니다. 여기 내 장치 클래스입니다 (클래스의 대부분의 편의를위한 필요의 유일한 것은 connection 멤버입니다

class Device: 
    def __init__(self): 
     self.connection = MonkeyRunner.waitForConnection() 
     self.width = int(self.connection.getProperty('display.width')) 
     self.height = int(self.connection.getProperty('display.height')) 
     self.model = self.connection.getProperty('build.model') 

    def touch(self, x, y, press=MonkeyDevice.DOWN_AND_UP): 
     self.connection.touch(x, y, press) 

데코레이터 사용하는 방법에 대한 예 :

@check_connection 
def screenshot(device, filename): 
    screen = device.connection.takeSnapshot() 
    screen.writeToFile(filename + '.png', 'png') 
+0

: 부록으로, 나는 또한 자바 오류를 발견하는 방법을 발견 'adb' 불안정성이지만 MonkeyRuner/Chimpchat 불안정성. [AndroidViewclient/culebra] (https://github.com/dtmilano/AndroidViewClient)는'adbclient'를 사용합니다.이 모듈은 모든 대화 상자를'adb'로 캡슐화하고 꽤 안정적입니다. –

6

당신이 얻을 것이다 장치의 monkey --port 12345 명령 스크립트가 정지 할 때 정지하지 않기 때문에 당신이 MonkeyRunner를 시작할 때마다 홀수 시간을 오류. 그것은 원숭이의 버그입니다.

이 문제를 해결하기위한 더 좋은 방법은 원숭이 때,213을 죽이고있다 210이 스크립트로 전송됩니다 (ctrl+c). 다른 말로 : $ killall com.android.commands.monkey.

빠른 방법은 그것을 할 수 있습니다 :

from sys, signal 
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice 

device = None 

def execute(): 
    device = MonkeyRunner.waitForConnection() 
    # your code 

def exitGracefully(self, signum, frame): 
    signal.signal(signal.SIGINT, signal.getsignal(signal.SIGINT)) 
    device.shell('killall com.android.commands.monkey') 
    sys.exit(1) 

if __name__ == '__main__' 
    signal.signal(signal.SIGINT, exitGracefully) 
    execute() 

편집 : 글쎄, 난 그 때문에하지 상기해야 Monkey Runner throwing socket exception broken pipe on touuch