解决 Airtest 启动 APP 自动翻转屏幕问题的三种方法

在 Android 平台上,使用 Airtest 启动应用时,可能会遇到一个问题:即便应用启动前已经将手机屏幕方向锁定,使用 Airtest 启动应用时,屏幕仍然会自动翻转。这通常是由于设备的重力感应导致的,尤其是在启动过程中,应用的界面可能会依赖重力感应来确定屏幕的方向。为了解决这个问题,我们可以采取两种有效的解决方法,以确保测试过程中屏幕不会自动翻转。

以下将详细介绍这三种方法,并结合源码分析及步骤进行解释。

方法一:在启动应用后禁用自动旋转

在启动应用后,我们可以通过禁用设备的重力感应来防止屏幕自动旋转。通过调用 `adb` 命令禁用设备的自动旋转功能,可以确保屏幕在测试过程中保持固定方向。

步骤:
  1. 分析 start_app函数源码: start_app 是 Airtest 中用于启动应用的主要函数,源码如下:
python 复制代码
@logwrap
def start_app(package, activity=None):
    """
    Start the target application on device

    :param package: name of the package to be started, e.g. "com.netease.my"
    :param activity: the activity to start, default is None which means the main activity
    :return: None
    :platforms: Android, iOS
    :Example:
        >>> start_app("com.netease.cloudmusic")
        >>> start_app("com.apple.mobilesafari")  # on iOS
    """
    G.DEVICE.start_app(package, activity)

该函数会调用 G.DEVICE.start_app 来启动应用,package 是应用的包名,activity 是应用的启动页面(默认为 None,表示启动默认的主界面)。 2. 分析 G.DEVICE.start_app 源码: start_app 函数会通过 adb shell 执行命令来启动应用,具体如下:

python 复制代码
    def start_app(self, package, activity=None):
        """
        Perform `adb shell monkey` commands to start the application, if `activity` argument is `None`, then
        `adb shell am start` command is used.

        Args:
            package: package name
            activity: activity name

        Returns:
            None

        """
        if not activity:
            try:
                ret = self.shell(['monkey', '-p', package, '-c', 'android.intent.category.LAUNCHER', '1'])
            except AdbShellError as e:
                raise AirtestError("Starting App: %s Failed! No activities found to run." % package)
            if "No activities found to run" in ret:
                raise AirtestError("Starting App: %s Failed! No activities found to run." % package)
        else:
            self.shell(['am', 'start', '-n', '%s/%s.%s' % (package, package, activity)])

如果 activity 参数为空,使用 adb shell monkey 启动应用。如果提供了 activity,则使用 adb shell am start 启动特定的 Activity。 3. 禁用自动旋转:通过 adb 命令禁用设备的自动旋转功能:

plain 复制代码
dev.shell("settings put system accelerometer_rotation 0")

. 4. 完整示例代码:

python 复制代码
deviceID = "你的设备id"
app = "com.xxxx"
activity = "com.ss.android.xxxx"
dev = connect_device(f"Android://127.0.0.1:5037/{deviceID}")

# 启动应用
start_app(app)
# 禁止自动旋转屏幕
dev.shell("settings put system accelerometer_rotation 0")

在这段代码中,我们先启动应用 app,然后通过 dev.shell("settings put system accelerometer_rotation 0") 禁用了设备的加速度感应旋转功能。这样,在测试过程中,屏幕方向将会自动调整过来。

方法二:指定启动特定的 Activity

我们可以在启动应用时,明确指定启动的 `Activity`,这样也能有效避免应用启动时触发自动旋转的界面。

步骤:
  1. 分析 start_app函数源码:如果提供了 `activity` 参数,`start_app` 会使用 `adb shell am start` 命令启动特定的 Activity:
python 复制代码
    def start_app(self, package, activity=None):
        """
        Perform `adb shell monkey` commands to start the application, if `activity` argument is `None`, then
        `adb shell am start` command is used.

        Args:
            package: package name
            activity: activity name

        Returns:
            None

        """
        if not activity:
            try:
                ret = self.shell(['monkey', '-p', package, '-c', 'android.intent.category.LAUNCHER', '1'])
            except AdbShellError as e:
                raise AirtestError("Starting App: %s Failed! No activities found to run." % package)
            if "No activities found to run" in ret:
                raise AirtestError("Starting App: %s Failed! No activities found to run." % package)
        else:
            self.shell(['am', 'start', '-n', '%s/%s.%s' % (package, package, activity)])

注意如上源代码通过 self.shell(['am', 'start', '-n', '%s/%s.%s' % (package, package, activity)]) 来启动app其实是有问题的,我们可以参考github.com/mzlogin/awe...

调整为self.shell(['am', 'start', '-n', '%s/%s' % (package, activity)]),如下是修改后的源码

python 复制代码
def start_app(self, package, activity=None):
    """
        Perform `adb shell monkey` commands to start the application, if `activity` argument is `None`, then
        `adb shell am start` command is used.

        Args:
            package: package name
            activity: activity name

        Returns:
            None

        """
    if not activity:
        try:
            ret = self.shell(['monkey', '-p', package, '-c', 'android.intent.category.LAUNCHER', '1'])
        except AdbShellError as e:
            raise AirtestError("Starting App: %s Failed! No activities found to run." % package)
            if "No activities found to run" in ret:
                raise AirtestError("Starting App: %s Failed! No activities found to run." % package)
    else:
        # 注释原来错误的启动命令
        # self.shell(['am', 'start', '-n', '%s/%s.%s' % (package, package, activity)])
        # 更改为正确的启动命令
        self.shell(['am', 'start', '-n', '%s/%s' % (package, activity)])

在此方法中,我们通过传入 activity 参数,明确指定要启动的 SplashActivity,这样可以确保应用启动时不会进入导致自动旋转的界面。 2. 传入 activity 参数: 通过明确指定要启动的 Activity,可以避免应用在启动过程中进入导致自动旋转的界面。

  1. 完整示例代码:
python 复制代码
deviceID = "你的设备id"
app = "com.xxxx"
activity = "com.ss.android.xxxx"
dev = connect_device(f"Android://127.0.0.1:5037/{deviceID}")

# 使用方式二,明确指定 Activity 启动
start_app(youtube_app, activity)

在此方法中,我们通过传入 activity 参数,明确指定要启动的 SplashActivity,这样可以确保应用启动时不会进入导致自动旋转的界面。

方法三:物理解决方案------人为立起手机

如果因设备限制无法使用软件方法,或者测试环境无法更改系统设置,可以采用物理方式将手机固定在直立状态,利用设备的重力感应特性避免屏幕旋转。

步骤:
  1. 将手机立起: 将手机垂直放置在平稳的桌面或支架上,确保屏幕正对前方。

  2. 启动应用: 使用 start_app 或其他方法启动应用。在手机处于直立状态时,设备的重力感应通常不会触发屏幕方向切换。

总结

  1. 方法一:禁用自动旋转。 通过禁用设备的重力感应旋转功能,确保应用启动后,屏幕不会因为设备的重力感应而自动翻转。这种方法适用于任何安卓应用,且实现简单。

  2. 方法二:指定启动特定的 Activity。 在启动应用时,通过明确指定要启动的 Activity,避免应用在启动过程中进入可能导致屏幕自动旋转的界面。这种方法适用于应用有多个启动界面时,能够保证启动过程的稳定性,但有小数app不起作用。

  3. 方法三:立起手机。 快速直接,无需修改系统或代码, 临时测试、环境限制时可尝试。

  • 获取当前屏幕活跃package, activity的ADB指令
shell 复制代码
adb -s 你的设备ID shell dumpsys window | findstr mCurrentFocus

在实际场景中,建议优先选择方法一方法二 ,因为它们能在系统层面或逻辑层面稳定解决问题,通常情况下,方法一 禁用自动旋转会更加简单有效,但是会对测试有一定地性能影响。如果你能准确知道需要启动的 Activity,方法二 将更加精确、高效地控制启动过程,避免不必要的屏幕旋转。如果测试环境限制较多,方法三也是一个便捷的替代方案。

相关推荐
ada7_15 小时前
LeetCode(python)——543.二叉树的直径
数据结构·python·算法·leetcode·职场和发展
小白学大数据15 小时前
Python 多线程爬取社交媒体品牌反馈数据
开发语言·python·媒体
HAPPY酷15 小时前
压缩文件格式实战速查表 (纯文本版)
python
祝余Eleanor16 小时前
Day 31 类的定义和方法
开发语言·人工智能·python·机器学习
背心2块钱包邮16 小时前
第6节——微积分基本定理(Fundamental Theorem of Calculus,FTC)
人工智能·python·机器学习·matplotlib
larance16 小时前
修改jupyterlab 默认路径
python
老华带你飞16 小时前
汽车销售|汽车报价|基于Java汽车销售系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·后端·汽车
别叫我->学废了->lol在线等16 小时前
python单例模式下线程安全优化
python·安全·单例模式
西江6497616 小时前
【个人博客系统—测试报告】
python·功能测试·jmeter·pycharm·postman
uzong16 小时前
别让认知天花板,变成你的职业终点——技术人如何走出信息茧房
后端