任何更快的转储UI层次结构的方法?

时间:2014-12-02 18:59:30

标签: android android-layout android-ui android-uiautomator

现在我使用uiautomator会像这样转储UI:

adb shell uiautomator dump

它工作正常,但执行它需要大约3秒钟。所以我想知道是否有更快的方法呢?就像创建一个转储UI的服务一样,还是需要花费同样的时间?

2 个答案:

答案 0 :(得分:8)

猜猜我应该回答我自己的问题,因为我发现了一个更好的方法。我发现这个项目使用uiautomator togheter与轻量级rpc服务器,所以你可以发送命令到设备:

https://github.com/xiaocong/android-uiautomator-server#build

这使得倾销几乎立即并且工作得非常好。如果你想看看如何进行rpc调用,他还有一个python项目:

https://github.com/xiaocong/uiautomator

但我在这里创造了一个小例子。

启动服务器:

# Start the process
process = subprocess.Popen(
        'adb shell uiautomator runtest '
        'bundle.jar uiautomator-stub.jar '
        '-c com.github.uiautomatorstub.Stub', stdout=subprocess.PIPE, shell=True)
# Forward adb ports 
subprocess.call('adb forward tcp:9008 tcp:9009')

调用命令的函数(" ping"," dumpWindowHierarchy"等):

def send_command(self, method_name, *args):
    """
    Send command to the RPC server

    Args:
        method_name(string): Name of method to run
        *args: Arguments
    """
    data = {
        'jsonrpc': '2.0',
        'method': method_name,
        'id': 1,
    }
    if args:
        data['params'] = args
    request = urllib2.Request(
        'http://localhost:{0}/jsonrpc/0'.format(self.local_port),
        json.dumps(data),
        {
            'Content-type': 'application/json'
        })
    try:
        result = urllib2.urlopen(request, timeout=30)
    except Exception as e:
        return None
    if result is None:
        return None
    json_result = json.loads(result.read())
    if 'error' in json_result:
        raise JsonRPCError('1',
                           'Exception when sending command to '
                           'UIAutomatorServer: {0}'.format(
                               json_result['error']))
    return json_result['result']

请注意,您必须先将文件(bundle.jar anduiautomator-stub.jar)从第一个项目推送到设备,然后将它们放入" / data / local / tmp /"

答案 1 :(得分:0)

看起来像旧线程,但这是一个更新的解决方案。 这可以通过使用以下npm模块在JS / Node应用程序中简单地实现。该模块使用与上述答案中提到的服务器相同的服务器,但确实如此。

npm install uiautomator-server

然后在项目中添加以下代码:

const UIAutomator = require('uiautomator-server');

const myDevice = new UIAutomator((err, currDevice) => {

    if (err) {

    console.log(`Error starting UI Automator server : ${err}`);

    }
    console.log(`UI Automator server started`);

    currDevice.dump(false, (error, xmlDump) => {

      if (error) {

       console.log(`Error while getting dump : ${error}`);

      }
      console.log(`xmlDump in as string: ${xmlDump}`);

  });

});

启动服务器(创建新的automator对象)可能需要一些时间(大约1秒),但是一旦启动服务,转储和其他操作非常快,即大多数 300 ms 案例。 您可以创建一个新的UIAutomator对象,然后在以后对所有操作使用相同的实例