Is UiSelector deprecated in Android's UI Automator?
short answer: no, not in the formal sense. as of October 2026, UiSelector is still a public class in the androidx.test.uiautomator library, and as far as I can tell it does not carry a @Deprecated tag in the reference docs. but it is the older of two selector styles, and Google’s own guidance and newer APIs lean toward BySelector and UiObject2. so “not deprecated” and “what you should reach for first” are two different answers.
this question shows up a lot, including in the appium-uiautomator2-driver issue tracker (issue 812). I’ll answer it directly below, then explain the two selector families.
what it is
UI Automator is a UI testing framework that ships as part of AndroidX Test. you write code that finds things on screen (a button, a text field, a list row) and then taps them, types into them or reads their text. unlike Espresso, which lives inside your app’s process, UI Automator works across app boundaries. it can open the Settings app, pull down the notification shade, or press Home. Google documents it on the UI Automator page of the Android developer site.
inside that library there are two generations of “find an element” API:
- UiSelector: the original. you build a selector with chained calls like
new UiSelector().text("Sign in").className("android.widget.Button"), then pass it toUiDevice.findObject(...)or into aUiObject. - BySelector: the newer one. you build it with the static
Byhelper, likeBy.text("Sign in").clazz("android.widget.Button"), and pass it toUiDevice.findObject(...), which returns aUiObject2.
so when people ask “is UiSelector deprecated”, they usually mean “is the whole UiSelector plus UiObject plus UiCollection plus UiScrollable family on its way out, and should I move everything to By plus UiObject2?”
how it works
the mechanism is the same in both families, and it helps to see it once.
UI Automator talks to Android’s accessibility layer. when you call findObject, the framework asks the system for a snapshot of the current window hierarchy, which is a tree of accessibility nodes. each node has properties: text, content description, resource ID, class name, whether it is clickable, scrollable, enabled and so on. your selector is a filter over that tree. the first node (or all nodes, depending on the call) that matches comes back to you.
here is where the two families differ in practice:
- UiSelector and UiObject are lazy. a
UiObjectis a description of an element, not a handle to a specific node. every time you callclick()orgetText(), it re-resolves the selector against a fresh hierarchy. that is forgiving, because the object never goes stale. it is also slower when you do many calls. - BySelector and UiObject2 are eager.
findObject(By...)resolves once and hands you aUiObject2bound to that node. if the screen changes under it, you can hit aStaleObjectExceptionand need to find the element again. in exchange you get a more direct API, plus helpers likeUntilconditions andwait(...)that make waiting for UI state cleaner. - the By family also has
UiDevice.wait(Until.hasObject(...), timeout)andUiObject2.wait(...), which is the idiomatic way to wait for something to appear. the UiSelector family haswaitForExists(...). - UiScrollable and UiCollection, the helpers for lists, belong to the UiSelector family. in the By family you scroll with
UiObject2.scroll(...)andfling(...), and you find list children through the node tree.
both ride on the same accessibility snapshot, so neither can see things the accessibility tree does not expose. a custom-drawn view with no accessibility info is invisible to both.
the Appium angle
this is where a lot of the confusion starts. if you drive Android through Appium with the UiAutomator2 driver, there is a locator strategy usually written as -android uiautomator, where you pass a string such as new UiSelector().text("Sign in"). the strategy name and the string format come from the UiSelector family. seeing “UiSelector” in Appium docs and then seeing UI Automator move toward By plus UiObject2 is what makes people suspect a deprecation.
the thing to keep straight: the Appium driver is its own project with its own server running on the device. which selector syntaxes it supports is decided by the appium-uiautomator2-driver repository and its docs, not by the AndroidX reference pages. when you read that project’s docs, check the current README for the supported locator strategies rather than assuming parity with the AndroidX library. and since I can’t promise what any given issue thread says today, read issue 812 itself for the maintainers’ wording.
why it matters
four reasons I’d care about this, as someone who runs real phones for a living:
- picking a style early saves rewrites. if you write a few hundred lines of tests against UiSelector and UiObject and later decide you want By plus UiObject2, you are rewriting every lookup and every wait. choosing deliberately on day one is cheap. migrating later is not.
- “deprecated” decides whether a library will break your build. a formal
@Deprecatedtag produces compiler warnings and usually signals removal at some point. no tag means no warning today. it does not mean a guarantee forever, so I treat it as a risk to re-check at each major library bump, not a promise. - the two styles fail differently. lazy UiObject hides staleness but can hide slowness. eager UiObject2 is quick but needs retry logic. knowing which failure you are looking at saves hours when a test is flaky.
- Appium users need to know which layer a problem lives in. if an
-android uiautomatorstring stops working, the cause is more likely in the Appium driver version or your server setup than in a deprecation in AndroidX. I cover related ground in can one android app control another through UI Automator, which explains the cross-app model that both selector families sit on.
common misconceptions
- “UiSelector is deprecated, so I must migrate now.” not as far as I can tell. as of October 2026 I’m not aware of a deprecation notice on the class in the androidx.test.uiautomator reference. the class page for UiSelector is the thing to check, because it is the authoritative source and it can change. if you see a deprecation banner there when you read this, trust the page over me.
- “BySelector replaces UiSelector one for one.” they overlap but they are not mirrors. BySelector has its own matching methods (
text,textContains,res,desc,clazzand others), and UiObject2 is a different object model, with its own waiting and scrolling behaviour. the BySelector reference lists what is available. expect to rewrite logic, not just rename classes. - “if UiSelector went away, Appium’s uiautomator locator would die too.” the link is looser than people assume. Appium’s driver runs its own server and decides its own supported syntax. a change in AndroidX would be something the Appium maintainers would have to respond to, and that is a separate decision on a separate timeline.
- “newer means faster.” not automatically. eager resolution avoids repeated hierarchy lookups, which can help, but I haven’t benchmarked the two and I won’t quote numbers. measure on your own app and your own device if speed matters to you.
where to go from here
a few practical next steps, depending on what you are doing:
- if you are setting up a test project, read do you need both instrumented android tests and appium in one project before you pick a selector style, because that choice often follows which runner you use.
- if your tests ship as a separate APK, installing a test-only APK with adb install -t covers the install flag that trips people up.
- if you need an unfamiliar app’s resource IDs for your selectors, how to pull an APK file off an android device with adb shows how to get the package so you can inspect it. only do this with apps you own or are authorised to test.
- if you are stuck before any of this starts, fixing a greyed-out USB debugging toggle on android covers the common blocker.
browse the rest of the site at /blog/.
a note on real devices
emulators are fine for learning selectors, but accessibility trees can differ between vendor skins, so I like to confirm on real hardware. if you don’t have a spare phone and your test target is a Singapore-based app or service, cloudf.one rents real Android phones in Singapore on dedicated hardware, each with a persistent Singapore mobile IP, controlled from the browser. it is Singapore-only. to be exact about adb: there is no self-service adb on cloudf.one. adb and Appium reach a rented phone only through a WireGuard tunnel that we set up on request (email [email protected]). so if your plan depends on running UI Automator or Appium against one, ask first and don’t assume it works out of the box. and as always, only automate apps and devices you own or are authorised to test.
the practical answer
if you want one line to take away: UiSelector is not formally deprecated as of October 2026, but the By family is where the newer ergonomics live. for a new project, I’d start with BySelector and UiObject2 and use Until waits. for an existing project already built on UiSelector, I would not rewrite just because of a rumour. re-check the reference page at each UI Automator version bump, and migrate when a real deprecation notice or a real flakiness problem gives you a reason.
Written by Xavier Fok
disclosure: this article may contain affiliate links. if you buy through them we may earn a commission at no extra cost to you. verdicts are independent of payouts. last reviewed by Xavier Fok on 2026-10-07.