如何使用uiautomator项目下的Instrumentation?

how to use Instrumentation under the uiautomator project?

我最近在做一个 uiautomator 项目,然后 UiObject.getFromParent 对我来说是一个错误的元素,我查看了 uiautomator 的源代码,发现答案是因为我使用的 UiSelector .

我发现 uiautomator 正在使用 Instrumentation 获取 UI 元素,就像 :

getInstrumentation().getUiAutomation().getRootInActiveWindow();

我只是想获取一个 AccessibilityNodeInfo 节点,就像 uiautomator 所做的那样,但 uiautomator 没有公开这个。

我正在通过一个新的 class 扩展 InstrumentationTestCase 来尝试这种方式,通过 getInstrumentation() 总是 return 对我来说是 null。

我找到了答案 android instrumentation test case - getinstrumentation() returning null 需要 injectInstrumentation(InstrumentationRegistry.getInstrumentation()); 并告诉 InstrumentationRegistry 来自官方 Android testing-support-lib:0.1

我已经下载 Android 支持存储库并将 testing-support-lib-0.1-source.jar 导入到我的项目中,但我仍然看不到 InstrumentationRegistry。

有人知道我的演员阵容吗?

嗯,这个问题已经被

解决了

unpack testing-support-lib-0.1.aar and get the classes.jar instead of testing-support-lib-0.1-source.jar

。现在 eclipse 不会说无法解决 anymore.By 的方式,你必须

add this lib to Ant's javac classpath by edit build.xml

否则你会得到一个在你尝试构建时找不到的库。 但现在新问题已经出现

INSTRUMENTATION_STATUS: stack=java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/test/InstrumentationRegistry;

也许这是另一个问题,所以我将通过 google 找出答案,如果弄清楚了我会更新这个,或者我会 post 一个新问题。

我正在使用 InstrumentationTestCase 的扩展,它像这样工作得很好:

@Override
public void setUp() throws Exception{
    super.setUp();
    Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
    AccessibilityNodeInfo root = instrumentation.getUiAutomation().getRootInActiveWindow();
}

我导入了

import android.test.InstrumentationTestCase;
import android.support.test.InstrumentationRegistry;
import android.view.accessibility.AccessibilityNodeInfo;

并安装

Android Support Repository (15)
Android Support Library (22.2)

希望对您有所帮助。

第一次尝试:

我注意到这个问题的重点是 uiautomator 没有公开我想要的 api,当我查看源代码并找到包含这些代码的 UiDevice.dumpWindowHierarchy 时:

AccessibilityNodeInfo root =getAutomatorBridge().getQueryController().getAccessibilityRootNode();
 the getAutomatorBridge was implemented by UiDevice:
   UiAutomatorBridge getAutomatorBridge() {
        if (mUiAutomationBridge == null) {
            throw new RuntimeException("UiDevice not initialized");
        }
        return mUiAutomationBridge;
    }

重点是没有修饰符,所以我把它的修饰符修改为public,修改了

的字节码

/system/framework/uiautomator.jar

还有一个在 sdk 中(抱歉我不知道,你可以用!我可以像这样使用它。

AccessibilityNodeInfo root =getUidevice().getAutomatorBridge().getQueryController().getAccessibilityRootNode();

但是存在兼容性问题,不是吗?

第二次尝试:

我们想一下java的默认修饰符,我们可以在同一个包下访问它,那么我们为什么不实现一个class具有相同的包名呢?那么我们可以在没有任何异常补丁的情况下调用它。 这就是我所做的,而且效果很好:

package com.android.uiautomator.core;

import android.view.Display;
import android.view.accessibility.AccessibilityNodeInfo;

public class AutomationUltilites
{
    public AutomationUltilites()
    {
    }
    public static AccessibilityNodeInfo  getRootNode()
    {
        return UiDevice.getInstance().getAutomatorBridge().getRootInActiveWindow();
    }
    public static Display getDisplay()
    {
        return UiDevice.getInstance().getAutomatorBridge().getDefaultDisplay();
    }
}

希望对您有所帮助。