Files
auto_control/core/u2_helper.py
T

115 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""uiautomator2 通用辅助函数。
所有任务都可复用:应用启动保障、等待首页、安全点击、随机操作等。
具体业务逻辑(如抖音首页特征元素判断)不放这里,放各自 task 文件。
"""
import time
import random
from core.logger import get_logger
_log = get_logger("core.u2")
def ensure_app_running(d, package, max_restart=3, home_check=None):
"""确保 app 在前台运行,被人为退出/崩溃则自动重启。
d: u2.Device
package: 包名
max_restart: 最大重启次数
home_check: 可选回调 d->bool,判断是否进入主页。
默认只看包名(包名对就返回 True,和原抖音逻辑一致)。
返回 True 表示 app 在前台;连续重启失败返回 False。
"""
home_check = home_check or (lambda d: True)
for attempt in range(1, max_restart + 1):
try:
cur = d.app_current()
except Exception:
cur = {}
if cur.get("package") == package and home_check(d):
return True
_log.info(f"{package} 不在前台(当前:{cur}),第 {attempt}/{max_restart} 次重启...")
try:
d.app_start(package, wait=True)
time.sleep(3)
if home_check(d):
return True
except Exception as e:
_log.warning(f"重启异常: {e}")
time.sleep(3)
return False
def wait_for_app_home(d, package, home_check, timeout=40):
"""等待 app 进入主页。
home_check: d->bool 回调,返回 True 表示已进入主页。
抖音主页 Activity 名仍叫 SplashActivity,不能靠 Activity 名判断,
要用界面特征元素(由调用方通过 home_check 传入)。
"""
deadline = time.time() + timeout
while time.time() < deadline:
try:
cur = d.app_current()
except Exception:
cur = {}
if cur.get("package") == package and home_check(d):
return True
time.sleep(2)
return False
def random_sleep(min_s, max_s):
"""随机睡眠(模拟人类操作间隔)。"""
time.sleep(random.uniform(min_s, max_s))
def safe_click(el, timeout=1):
"""安全点击:元素存在才点,不抛异常。返回是否点击成功。"""
try:
if el.exists(timeout=timeout):
el.click()
return True
except Exception:
pass
return False
def safe_set_text(el, text, timeout=1):
"""安全输入文本:元素存在才输入,不抛异常。返回是否成功。"""
try:
if el.exists(timeout=timeout):
el.set_text(text)
return True
except Exception:
pass
return False
def find_and_click(d, timeout=1, **selectors):
"""按定位器找元素并点击,找不到不抛异常。返回是否成功。
用法:find_and_click(d, text="首页") 或 find_and_click(d, description="搜索")
"""
try:
el = d(**selectors)
if el.exists(timeout=timeout):
el.click()
return True
except Exception:
pass
return False
def random_swipe_up(d, width_ratio=0.5, height_start=0.8, height_end=0.2, duration=None):
"""随机上滑(刷视频常用)。坐标按屏幕比例算,适配不同分辨率。
duration: 滑动时长(秒),None 则随机 0.25~0.50s。
"""
info = d.info
w, h = info["displayWidth"], info["displayHeight"]
dur = duration or random.uniform(0.25, 0.50)
d.swipe(int(w * width_ratio), int(h * height_start),
int(w * width_ratio), int(h * height_end), dur)