除了 UIAutomator 2.0 版本名称之外,UIObject 和 UIObject2 之间的区别是什么?

whats is the difference between UIObject and UIObject2 other than UIAutomator 2.0 version name?

我在 Android 开发者网站上进行了谷歌搜索和搜索,但找不到合适的答案。谁能帮我解决这个问题?提前致谢。

UiObject:
UiObject 是一个视图的表示。 它不以任何方式作为对象引用直接绑定到视图。 UiObject 包含帮助它在运行时定位匹配视图的信息 基于其构造函数中指定的 UiSelector 属性。 一旦你创建了一个 UiObject 的实例,它就可以被重新用于不同的 符合选择器条件的视图。

https://developer.android.com/reference/android/support/test/uiautomator/UiObject.html

UiObject2:
UiObject2 表示 UI 元素。与 UiObject 不同,它绑定到一个 特定的视图实例,如果底层视图对象被销毁,它可能会变得陈旧。 因此,可能需要调用 findObject(BySelector) 来获取 新的 UiObject2 实例,如果 UI 发生显着变化。

https://developer.android.com/reference/android/support/test/uiautomator/UiObject2.html

主要区别:

  1. 他们代表什么
  2. 等待观看 exist/finding 观看
  3. 滚动

他们代表什么

用我的话说,UiObject2 是直接 存在于屏幕上的真实视图 表示,允许您在屏幕上执行操作那个观点。 UiObject 是 howfind 一个 may 在屏幕上的元素的表示,结合 你可以采取的行动

UiObject as the docs say,表示在屏幕上查找内容的方法。这意味着您可以在以后重新使用 UiObject 实例来查找匹配元素的另一个实例。

例如:您可以使用 UiObject api (UiDevice.findObject(UiSelector)) 在一个屏幕上找到工具栏以获取 UiObject 的实例,然后打开模式对话框。关闭对话框后,您可以使用同一实例再次访问工具栏。

UiObject2 as the docs say,表示页面上某个项目的特定实例,因此不能重复使用稍后以与 UiObject 相同的方式查找另一个元素。如果您有一个 UiObject2 实例,那么您 "guarantee" 页面上存在与该实例匹配的视图,并且该实例只能真正使用一次。

在与上述相同的示例中,模式对话框关闭后,您必须使用 UiObject2 api (UiDevice.findObject(Until....)) 来检索 新实例 表示工具栏的 UiObject2,因为到那时旧的已经过时了。

等待观看 exist/finding 观看

您可能希望在执行操作后等待视图出现在页面上。有两种方法可以做到这一点:

  1. UiDevice.findObject(UiSelector) (returns UiObject) 后跟 UiObject.waitForExists(超时)
  2. UiDevice.wait(Until.findObject(SearchCondition), timeout) (returns UiObject2)

两种情况下,timeout都是long类型

这是现在的api有点不一致的地方。为了使用上面的方法 #2,您必须使用 Until and By 实用程序 classes 来描述如何在屏幕上找到视图。而对于方法 #1,您只使用 UiSelector 方法。

您会在 By 实用程序 class 上找到与 UiSelector class 上类似的方法,但方法名称完全不同。例如By.res(String resourceName) accomplishes the same thing as UiSelector.resourceId(String id),但显然有不同的名字,让你觉得他们完成了不同的事情。

在我看来:UiObject api更好,因为定位视图不同于等待视图的操作。这使您可以随时等待要查找的任何视图。另一方面,UiObject2 api 强制您选择要做什么:您调用 device.findObject(By...) 或调用 device.wait(Until.findObject(By...)),但您被迫选择是否等待或者不提前。

滚动

一个 UiObject2 有一个 "bare bones" 滚动方法:UiObject2.scroll(Direction, percentage)。此方法允许您以预先指定的滚动量沿特定方向滚动,但绝对不是很方便,因为用户必须决定滚动多少。我可以看到这个方法被放入一个循环中:滚动,检查元素是否可见,重复。

另一方面,

UiScrollable 具有更更方便 滚动的方法:例如 UiScrollable.scrollIntoView(...)。此方法采用 UiSelector 并显示为 "do what must be done" 以在该 UiSelector 上进行匹配并使其可见。这比 UiObject2 有用得多,因为 api 会为您处理一切,不需要循环。

额外的不一致

要获取 UiObject 的实例,您必须在 UiDevice 上使用方法,例如 UiDevice.findObject(UiSelector)。您过去可以直接实例化一个 UiObject,但该构造函数在 February, 2014 中已被弃用,因为它隐藏了它正在使用 UiDevice 查找元素的事实。

UiScrollable 是 UiObject 的子class。 UiScrollable 有 one constructor 以 UiSelector 作为参数。这个构造函数简单地调用 super 直到它到达上面提到的 UiObject 的弃用构造函数。

重申一下:你只能通过UiDevice获得一个UiObject。但是要得到一个 UiScrollable,你只能直接实例化它,使用已经被标记为 deprecated 的构造函数。

意见:语义命名

在我看来:如果将 UiObject2 命名为 ResolvedUiObject 之类的名称,它会使 api 的意图更加清晰。 UiObject2 没有传达 class 的语义目的,因此导致了这个 Whosebug 问题。

我几乎可以说 UiObject.waitForExists() 应该 return UiObject2 就像它写的那样,因为 UiObject 基本上用作定位器(虽然我猜,这就是 UiSelctor 是什么:/ ) 的视图结合了对视图执行的操作,而 UiObject2 包含仅对视图执行操作的方法。