韩师傅就是我

测试开发工程师

appium为什么不能想启动哪个就启动哪个Activity

前言

使用appium做安卓app的自动化,第一件事儿就是启动一个activity(也就是页面)。一个app里有那么多页面,如果我想测试哪个页面就直接启动哪个页面该多好。但事实是,一个应用市场包中(非debug包),只有很少的页面可以被外部应用(另一个进程,比如appium)直接启动。所以在自动化脚本中,你只能先启动主页面,然后一步一步的走到被测试页面。那么问题来了,到底哪些activity可以直接被appium启动呢?

答案在manifest.xml文件中找,规则就2条,非常简单。

规则1,先看Activity 的 android:exported 属性

AndroidManifest.xml 中,每个 <activity> 标签的 android:exported 属性决定了该 Activity 是否允许被外部组件(如 Appium)启动:

  • android:exported="true":允许外部启动。
  • android:exported="false":仅允许同一应用或特权进程启动。

规则2,未显式设置 exported 属性的,看有没有 <intent-filter>

  • 如果该 Activity 声明了 <intent-filter>,则默认 exported=true
  • 如果没有 <intent-filter>,则默认 exported=false

举个栗子

<!-- 允许外部启动(显式或隐式) -->
<activity android:name=".MainActivity" android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<!-- 仅允许同一应用启动 -->
<activity android:name=".InternalActivity" android:exported="false" />

<!-- 默认允许外部启动(因有intent-filter) -->
<activity android:name=".WebActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="https" />
    </intent-filter>
</activity>

如何启动

声明了android:exported=”true”的Activity,可以通过Activity 的完整组件名(包名 + 类名)启动。(所谓的显示启动)

# Python + Appium 示例,显式启动Activity
driver.start_activity(app_package="com.example.pkg", app_activity=".MainActivity")

没声明exported=true,但声明了 <intent-filter>的Activity,可以通过Intent 的 actiondata 启动(所谓的隐式启动)

# Python + Appium 示例,启动系统浏览器打开网页(隐式Intent)
driver.execute_script('mobile: startActivity', {
    'action': 'android.intent.action.VIEW',
    'data': 'https://example.com'
})

为什么我作为一个APP要允许别的APP打开我的页面

  • 分享
  • 支付

为什么需要隐式启动?

  • 解耦调用方与被调用方:调用方无需知道具体实现类的包名,只需声明意图(如“分享”)。
  • 多应用竞争:多个应用可以注册同一 Intent 过滤器,用户可自由选择默认应用。(你最常见的下图,就是隐式启动的效果)
appium为什么不能想启动哪个就启动哪个Activity

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Scroll to top