2023年6月28日发(作者:)
Airtest源码分析--Android屏幕截图⽅式上期回顾:以下基于airtest1.2.0airtest中安卓的屏幕截图代码都在/airtest/core/android/cap_methods/该⽬录结构为.├── base_├── ├── ├── └── screen__其中的BaseCap类是所有屏幕截图⽅法的基类,定义了⼀些基本的⽅法,其他具体截图⽅法类使⽤或重写这些⽅法。
cap类基于stf的minicap。通过adb forward设置airtest和⼿机端的端⼝映射关系,建⽴⼀个socket持续获取minicap stream,应该就是airtestIDE中的投屏基础。 def get_stream(self, lazy=True): """ Get stream, it uses `adb forward`and socket communication. Use minicap ``lazy``mode (provided by gzmaruijie) for long connections - returns one latest frame from the server Args: lazy: True or Fals """ gen = self._get_stream(lazy) # if quirk error, restart server and client once stopped = next(gen) if stopped: try: next(gen) except StopIteration: pass gen = self._get_stream(lazy) next(gen) return gen通过adb minicap -s命令获取⼀帧截图,以实现airtestIDE中的截图及对⽐的基础。 def get_frame(self, projection=None): """ Get the single frame from minicap -s, this method slower than `get_frames` 1. shell cmd 1. remove log info 1. rrn -> n ... Args: projection: screenshot projection, default is None which means using tion Returns: jpg data """ params, display_info = self._get_params(projection) if y_id: raw_data = _shell( + " -d " + str(y_id) + " -n 'airtest_minicap' -P %dx%d@%dx%d/%d -s" % params, ensure_unicode=False, ) else: raw_data = _shell( + " -n 'airtest_minicap' -P %dx%d@%dx%d/%d -s" % params, ensure_unicode=False, ) jpg_data = raw_(b"for JPG encoder" + _breaker)[-1] jpg_data = jpg_e(_breaker, b"n") return jpg_data
ap类就是通过adb shell screencap -p来获取屏幕截图class AdbCap(BaseCap): def get_frame_from_stream(self): ("Currently using ADB screenshots, the efficiency may be very low.") return ot() def snapshot(self, ensure_orientation=True): screen = super(AdbCap, self).snapshot() if ensure_orientation and _version <= SDK_VERISON_ANDROID7: screen = (screen, y_info["orientation"] * 90, clockwise=False) return screen看⼀下其调⽤的ot()⽅法def snapshot(self): """ Take the screenshot of the device display Returns: command output (stdout) """ if y_id: raw = ('shell screencap -d {0} -p'.format(y_id), ensure_unicode=False) else: raw = ('shell screencap -p', ensure_unicode=False) return e(_breaker, b"n")cap类基于yosemite作为service,建⽴socket连接和airtest通讯,提供截图。性能⽐minicap差,但兼容性⾼,有些机型不⽀持minicap。screen_enProxy类,屏幕代理,airtest1.2.0引⼊。在以前遇到特殊机型,是要提供特殊的连接参数的,如cap_method="JAVACAP",或在airtestIDE连接前选中JAVACAP。从airtest1.2.0、airtestIDE1.2.10开始,就不需要再指定连接参数了,airtest会⾃⼰去进⾏适配,按性能初始化顺序为⾃定义⽅法 > MINICAP> JAVACAP > ADBCAP,如果调⽤到了ADBCAP,将会打印⼀个warning,告诉⽤户此时截图效率很低。这样,以后⽆需再关注底层到底⽤的是谁,需要截图时直接通过screen_proxy即可,例如:dev = Android()screen_proxy = _setup(, rotation_watcher=on_watcher)screen__frame_from_stream()screen_wn_stream()如果希望实现⾃定义的新截图⽅法:在__cap中,实现了所有截图⽅法的基类BaseCap,可以通过继承它,并实现get_frame_from_stream这个接⼝,就能新增⼀个⾃定义的截图⽅法,将它注册到ScreenProxy中就可以使⽤了。from __cap import BaseCapclass TestCap(BaseCap): def get_frame_from_stream(self): return b"frame"er_method("TESTCPY", TestCap)# 默认优先初始化为⾃定义的TestCapcap = _setup()总结划重点,MINICAP性能最好,JAVACAP性能次之但兼容性好,ADBCAP性能最差。---------------------------------------------------------------------------------关注微信公众号即可在⼿机上查阅,并可接收更多测试分享~
发布者:admin,转转请注明出处:http://www.yc00.com/web/1687955487a60616.html
评论列表(0条)