You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Appium中driver.startActivity()替代方案及空指针异常问题咨询

问题描述

环境:Appium 2.2.3、Java JDK 17.05、Appium Java Client 9.0.0、TestNG 7.8.0

运行以下代码时触发空指针异常,现寻求该代码的替代方案,同时需要能在同一个类中运行多个@Test方法的App包名和Activity配置方式:

原代码:

Activity activity = new Activity("com.androidsample.generalstore",
"com.androidsample.generalstore.MainActivity");
    driver.startActivity(activity);

在@BeforeMethod中尝试的代码:

@BeforeMethod (alwaysRun=true)  
public void setActivity() {
    Activity activity = new Activity("com.androidsample.generalstore",
"com.androidsample.generalstore.MainActivity");
    driver.startActivity(activity);
    }

报错信息:

java.lang.NullPointerException: 无法调用"pageObjects.android.FormPage.setActivity()",因为"this.formPage"为null
    at testCases.eCommerce_tc_2.preSetup(eCommerce_tc_2.java:18)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139)
    at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69)
    at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390)
    at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325)
    at org.testng.internal.invokers.TestInvoker.runConfigMethods(TestInvoker.java:810)
    at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:577)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:227)
    at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:50)
    at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:957)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:200)
    at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:148)
    at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:128)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.testng.TestRunner.privateRun(TestRunner.java:848)
    at org.testng.TestRunner.run(TestRunner.java:621)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:443)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:437)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:397)
    at org.testng.SuiteRunner.run(SuiteRunner.java:336)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1200)
    at org.testng.TestNG.runSuites(TestNG.java:1114)
    at org.testng.TestNG.run(TestNG.java:1082)
    at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
解决方案

先修复空指针异常

报错核心是this.formPage未初始化就被调用,需在调用formPage.setActivity()前完成实例化:

@BeforeMethod(alwaysRun = true)
public void preSetup() {
    // 先初始化page对象
    formPage = new FormPage(driver);
    // 再执行相关操作
    formPage.setActivity();
}

配置App包名和Activity的替代方式

方式1:Driver初始化时通过Desired Capabilities指定(全局生效)

创建Driver实例时直接配置appPackage和appActivity,所有@Test方法启动时都会自动打开目标页面:

@BeforeClass(alwaysRun = true)
public void setupDriver() throws MalformedURLException {
    DesiredCapabilities caps = new DesiredCapabilities();
    caps.setCapability("platformName", "Android");
    caps.setCapability("appium:deviceName", "你的设备名称");
    caps.setCapability("appium:appPackage", "com.androidsample.generalstore");
    caps.setCapability("appium:appActivity", "com.androidsample.generalstore.MainActivity");
    // 其他必要配置,如automationName等
    driver = new AndroidDriver(new URL("http://localhost:4723/wd/hub"), caps);
}

方式2:使用AppiumOptions配置(Appium 2.x推荐)

Appium 2.x官方更推荐用AppiumOptions替代Desired Capabilities,写法更简洁:

@BeforeClass(alwaysRun = true)
public void setupDriver() throws MalformedURLException {
    AppiumOptions options = new AppiumOptions();
    options.setPlatformName("Android");
    options.setDeviceName("你的设备名称");
    options.setAppPackage("com.androidsample.generalstore");
    options.setAppActivity("com.androidsample.generalstore.MainActivity");
    // 其他配置
    driver = new AndroidDriver(new URL("http://localhost:4723/wd/hub"), options);
}

方式3:@BeforeMethod中重置App并启动Activity(用例独立状态)

如果每个@Test需要独立的App初始状态,可在@BeforeMethod中重置App后再启动目标Activity:

@BeforeMethod(alwaysRun = true)
public void resetAndLaunch() {
    // 重置App到初始状态
    driver.resetApp();
    // 启动指定Activity
    Activity activity = new Activity("com.androidsample.generalstore", 
                                    "com.androidsample.generalstore.MainActivity");
    driver.startActivity(activity);
    // 确保page对象已初始化
    if (formPage == null) {
        formPage = new FormPage(driver);
    }
}

方式4:通过adb命令启动Activity(绕过Appium API)

如果startActivity方法存在问题,可直接执行adb命令启动目标页面:

@BeforeMethod(alwaysRun = true)
public void launchViaAdb() {
    try {
        // 执行adb启动命令
        Runtime.getRuntime().exec("adb shell am start -n com.androidsample.generalstore/.MainActivity");
        // 等待页面加载
        Thread.sleep(2000);
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
    }
}

内容的提问来源于stack exchange,提问作者Burhan Guvenc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:00:57