解决 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,方法二 将更加精确、高效地控制启动过程,避免不必要的屏幕旋转。如果测试环境限制较多,方法三也是一个便捷的替代方案。

相关推荐
测试19983 分钟前
Jmeter进行http接口测试
自动化测试·软件测试·python·测试工具·jmeter·http·职场和发展
LeonNo1110 分钟前
golang,多个proxy拉包的处理逻辑
开发语言·后端·golang
Python私教17 分钟前
Passlib库介绍及使用指南
python
龙少954323 分钟前
【springboot中最适合用什么技术来实现在线聊天】
java·spring boot·后端
xiaocaibao77727 分钟前
Bash语言的语法
开发语言·后端·golang
FreedomLeo11 小时前
Python机器学习笔记(十六、数据表示与特征工程-分类变量)
python·机器学习·数据表示与特征工程·分类变量·连续特征·分类特征
江南野栀子1 小时前
数据可视化-16. 日历图
python·信息可视化·数据挖掘·dash
憨憨小江1 小时前
SpringBoot接收参数
chrome·spring boot·后端
van叶~2 小时前
仓颉语言实战——1. 类型
开发语言·windows·python·仓颉
万亿少女的梦1682 小时前
高校网络安全存在的问题与对策研究
java·开发语言·前端·网络·数据库·python