Skip to content

Instantly share code, notes, and snippets.

@codeskyblue
Last active September 30, 2025 08:23
Show Gist options
  • Select an option

  • Save codeskyblue/67b462f2e9952ce3db7d5dcaac7dd809 to your computer and use it in GitHub Desktop.

Select an option

Save codeskyblue/67b462f2e9952ce3db7d5dcaac7dd809 to your computer and use it in GitHub Desktop.
uiautomator2使用自定义弹窗监控的例子
# author: codeskyblue 2025
# https://github.com/openatx/uiautomator2
# Example: how to manually handle popup-windows
import random
import time
from typing import Optional, Sequence, Tuple
import adbutils
from loguru import logger
from uiautomator2 import Device as U2Device
from uiautomator2.xpath import PageSource, XMLElement
class PopupRule:
def __init__(self, target: str, neighbors: Optional[Sequence[str]] = None):
self.target = target
self.neighbors = neighbors or ()
def get_match(self, page_source: PageSource) -> Optional[XMLElement]:
for xpath in self.neighbors:
elements = page_source.find_elements(xpath)
if not elements:
return None
els = page_source.find_elements(self.target)
return els[0] if els else None
POPUP_RULES = (
PopupRule('//*[@content-desc="继续"]'),
PopupRule('//android.widget.Button[@text="继续"]'),
PopupRule('//*[@text="以后再说"]', neighbors=['//*[@text="Google 存储空间备份"]']),
)
class MyDevice:
def __init__(self, serial: Optional[str] = None):
self.u2 = U2Device(serial or adbutils.device())
def click(self, x: int, y: int):
self.u2.click(x, y)
def _handle_popup(self, page_source: PageSource) -> bool:
popups = list(POPUP_RULES)
random.shuffle(popups)
for rule in popups:
el = rule.get_match(page_source)
if el:
logger.info(f"检测到弹窗: {rule.target}, 点击关闭")
x, y = el.center()
self.click(x, y)
return True
return False
def get_stable_page_source(self) -> Tuple[PageSource, bool]: # has_popup
deadline = time.time() + 10
has_popup = False
while time.time() < deadline:
page_source = self.u2.xpath.get_page_source()
if self._handle_popup(page_source):
has_popup = True
continue
return page_source, has_popup
raise TimeoutError("未能在规定时间内稳定页面")
def click_by_xpath(self, xpath: str, timeout: float=30, nf_ok: bool = False):
# nf: not found
logger.debug(f"Click: {xpath}")
deadline = time.time() + timeout
while time.time() < deadline:
page_source, has_popup = self.get_stable_page_source()
if has_popup:
deadline = time.time() + timeout
els = page_source.find_elements(xpath)
if els:
self.click(*els[0].center())
return
else:
if nf_ok:
print("Not found, but OK:", xpath)
raise TimeoutError(f"未能在规定时间内点击到元素: {xpath}")
if __name__ == "__main__":
device = MyDevice()
device.click_by_xpath('//*[@text="证件"]')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment