将自动化脚本引擎集成到自己的app中

在 Android 行业开发场景中,大量工具类、运营类、测试类 App 存在标准化重复操作需求:如批量数据采集、自动表单填写、定时任务执行、APP 内部流程自动化测试等。传统实现方案分为两类,各自存在明显短板:第一种是独立自动化工具(AutoJS、Hamibot 等),用户需要同时安装主业务 App 与自动化工具,切换操作繁琐;且第三方工具无法和自研 App 做账号打通、权限隔离、业务数据互通,无法实现一体化产品体验;同时独立脚本工具存在分发、管控、脚本安全管控难题,企业级场景难以落地。第二种是基于 Android 原生无障碍、Airtest、Appium 自行封装脚本引擎,从零开发需要处理权限检测、JS 解析引擎、设备操作底层封装、脚本生命周期管理、前后端通信等大量底层逻辑,开发周期长、兼容性差,多机型适配、权限弹窗自动处理、定时任务调度等细节需要大量踩坑调试,中小开发团队投入成本极高。本文从环境准备、工程集成、生命周期调用、脚本交互、生产落地问题优化完整梳理集成全流程,为 Android 开发者提供可落地的工程实践方案。

一、SDK 核心能力与适用开发环境说明

(一)SDK 核心功能边界

冰狐移动端 SDK 完整继承独立 APP 全部核心自动化能力,对外提供标准化 Java 调用接口,核心能力覆盖:

  1. 引擎生命周期管理:初始化、登录、登出、页面生命周期绑定(Activity onCreate/onResume/onPause/onDestroy);
  2. 账号体系:自动登录、手动账号密码登录、子账户绑定、全局用户名 / 设备名读取;
  3. 脚本执行核心接口 exeScript:支持本地文件、Asset 资源、手机绝对路径、在线远程脚本四种加载方式,支持多任务抢占、执行后置默认任务、执行结果回调;
  4. 双向通信机制:setStateListener 全局状态监听、setMessageListener 系统消息回调;addJavaObject 实现 Java 对象注入 JS,JS 直接调用原生业务代码;
  5. 环境管控:静态方法切换生产 / 调试模式,区分线上正式环境与本地脚本调试环境;
  6. 内置底层依赖封装:网络通信 Netty、HTTP 请求 OkHttp、定时任务 cron4j,提供完整底层能力支撑。

(二)官方推荐开发环境规范

根据官方 Demo 文档,稳定适配构建环境组合如下,不匹配环境极易出现编译报错、依赖冲突、引擎初始化失败问题:

  1. Gradle 构建工具:gradle-8.0-bin;
  2. JDK 版本:Java17;
  3. IDE:Android Studio Giraffe;
  4. 工程编译方式:标准 Android Application 模块,支持 AAR 本地引入、本地 Maven 两种集成模式。

二、工程完整集成步骤与代码配置详解

集成分为SDK 文件导入、Gradle 依赖配置、底层第三方库引入三大基础步骤,同时提供两种依赖优化方案规避依赖冗余问题。

3.1 第一步:导入 SDK 本地 AAR 文件

从官方文档链接下载 Demo 包,提取 aznfz.aar 核心库文件,在项目 app 模块下新建 libs 文件夹,将 aar 文件完整拷贝至该目录,目录结构如下:

app/
└── libs/
    └── aznfz.aar

3.2 第二步:配置 Gradle 读取本地 AAR 库

打开 app 模块 build.gradle,在 dependencies 代码块中添加本地文件树依赖,读取 libs 下所有 aar 库:

dependencies {
    // 读取libs目录下所有AAR文件
    implementation(fileTree("libs"))
    // 业务自身其他依赖...
}

配置完成后点击 Android Studio 右侧 Maven Projects 面板刷新,同步 Gradle 工程,此时 IDE 可识别 SDK 内所有 Java 类与接口。

3.3 第三步:引入 SDK 必需底层第三方依赖

aznfz.aar 仅封装上层引擎业务逻辑,网络、定时、通信底层依赖未内置,必须手动添加三方库,否则运行时会抛出 ClassNotFound 异常,标准依赖配置如下:

implementation ('io.netty:netty-all:4.1.36.Final')
implementation ('com.squareup.okhttp3:okhttp:3.8.1')
implementation ('it.sauronsoftware.cron4j:cron4j:2.2.5')

3.4 两种优化集成方案(规避大量依赖配置)

官方文档提供两种方案,无需手动添加三个底层依赖,适合大型多模块项目:

  1. Fat AAR 全量包:下载打包完成的 Fat 版本 aznfz.aar,内部已内嵌所有第三方依赖,仅需引入文件树,无需额外配置 netty、okhttp、cron4j;缺点是 AAR 包体积增大,适合小型单模块项目。
  2. 本地 Maven 仓库:将 SDK 及依赖上传至项目本地 Maven 库,通过 maven 坐标引入,统一管理版本,适合多模块大型工程,便于统一升级 SDK 版本,减少重复依赖配置。

三、SDK 生命周期标准调用流程

官方 Demo 采用 StartupActivity(引擎初始化)→LoginActivity(手动登录)→MainActivity(脚本业务操作)三层页面架构,该生命周期流程是保障引擎稳定运行的核心规范,不可随意调整调用顺序,否则会出现权限检测失效、登录状态丢失、脚本无法执行等问题。

4.1 阶段一:StartupActivity 完成引擎初始化与自动登录

引擎初始化 init 方法建议在页面 onResume 中调用,支持重复调用,内部会自动校验无障碍、悬浮窗等自动化必需权限,缺失权限时主动弹窗引导用户开启。

1. init 初始化方法调用示例
SAR.getInstance().init(this, new InitListener() {
    @Override
    public void onInitResult(boolean success) {
        if (success) {
            // 初始化成功,执行自动登录
            autoLogin();
        } else {
            // 初始化失败,权限缺失或设备不支持,跳转提示页
        }
    }
});

init 接收两个入参:当前 Activity 上下文、初始化结果回调 InitListener,回调返回布尔值标识引擎是否初始化就绪。

2. autoLogin 自动登录逻辑

初始化成功后执行自动登录,复用本地缓存账号,无需用户重复输入账号密码:

private void autoLogin() {
    SAR.getInstance().autoLogin(getApplicationContext(), new LoginListener() {
        @Override
        public void onLoginResult(boolean success) {
            if (success) {
                // 自动登录成功,跳转MainActivity
                startActivity(new Intent(StartupActivity.this, MainActivity.class));
            } else {
                // 自动登录失败,跳转手动登录页面
                startActivity(new Intent(StartupActivity.this, LoginActivity.class));
            }
        }
    });
}

4.2 阶段二:LoginActivity 手动账号登录(自动登录失败兜底)

当本地无缓存账号、登录凭证过期时,进入手动登录页面,调用 login 方法,支持主账户、子账户两种登录模式:

// 普通主账户登录,parentName传空
SAR.getInstance().login(username, password, "", new LoginListener() {
    @Override
    public void onLoginResult(boolean success) {
        if (success) {
            startActivity(new Intent(LoginActivity.this, MainActivity.class));
        } else {
            // 提示账号密码错误
        }
    }
});
// 子账户登录,传入父账户名称
SAR.getInstance().login(childUser, childPwd, parentAccount, listener);

4.3 阶段三:MainActivity 绑定页面生命周期,执行业务脚本

登录成功后进入主业务页面,必须完整绑定四大生命周期方法,用于引擎资源释放、状态刷新,防止内存泄漏、后台脚本卡死:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    SAR.getInstance().onCreate(getApplicationContext());
}

@Override
protected void onResume() {
    super.onResume();
    SAR.getInstance().onResume();
}

@Override
protected void onPause() {
    super.onPause();
    SAR.getInstance().onPause();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    SAR.getInstance().onDestroy();
}

生命周期绑定完成后,即可注册全局监听、执行自动化脚本、注入 Java 交互对象,开展核心业务。

四、核心业务接口深度实践:脚本执行与 Java-JS 双向通信

5.1 exeScript 脚本执行接口全场景使用

exeScript 是 SDK 最核心业务接口,支持四类脚本资源路径,覆盖本地静态脚本、在线动态下发脚本场景,完整参数包含脚本路径、目标函数、任务抢占、入参数组、执行回调、后置默认任务开关。

场景 1:读取 App 内置 Asset 本地脚本
// 执行asset目录下test.js中的main函数,传入JSON数组参数,抢占当前任务
JSONArray params = new JSONArray();
params.put("批量采集");
SAR.getInstance().exeScript(
        "asset:test.js",
        "main",
        true,
        params,
        new ExecuteScriptResultListener() {
            @Override
            public void onResult(boolean success, String msg) {
                // 脚本执行完成回调,success为执行状态,msg为返回信息
            }
        },
        false
);
场景 2:执行手机本地存储 JS 文件
// 读取手机根目录脚本
SAR.getInstance().exeScript("/sdcard/batch_task.js", "runTask", false, params, listener, true);
场景 3:在线远程脚本(企业动态下发脚本场景)
// 直接调用后台发布的线上脚本,无需本地存储
SAR.getInstance().exeScript("online_task", "start", true, params, listener, false);

参数说明:forceRun 控制任务抢占,true 代表停止当前运行脚本立即执行新脚本;exeDefaultTaskWhenFinished 控制脚本执行完毕后是否自动执行平台默认定时任务,适合持续自动化运营场景。

5.2 全局状态与消息监听:业务联动能力

通过 setStateListener、setMessageListener 监听引擎内部状态、平台推送消息,实现业务联动:

  1. StateListener:监听登录状态、脚本运行状态、权限变更、生产模式切换;
  2. MessageListener:接收后台下发的通知、任务指令、设备告警消息。典型应用:脚本执行失败时收到状态回调,自动弹窗提示用户;后台推送新任务消息,自动触发 exeScript 执行对应脚本。

5.3 addJavaObject:Java 与 JS 双向交互(业务核心拓展能力)

该接口解决脚本无法调用 App 原生业务逻辑的痛点,允许将 Java 业务对象注入 JS 引擎,JS 脚本直接调用 Java 方法,支持数字、布尔、字符串、JS 数组、JS 对象五种数据类型互传。

1. 编写原生业务 Java 类
public class BusinessApi {
    // 字符串+数字入参
    public String getOrderInfo(String orderId, long userId) {
        return "订单信息:" + orderId + " 用户ID:" + userId;
    }
    // JS数组操作
    public long handleList(JSArray array) {
        array.push(System.currentTimeMillis());
        return array.getLength();
    }
    // JS对象传参
    public JSObject setConfig(JSObject config) {
        config.put("autoRun", true);
        return config;
    }
}
2. 引擎初始化完成后注入对象
SAR.getInstance().addJavaObject("businessApi", new BusinessApi());
3. JS 脚本中调用原生方法
function main() {
    // 调用Java获取订单
    let order = businessApi.getOrderInfo("ORD20260701", 10001);
    console.log(order);
    // JS数组传递至Java
    let arr = ["任务1", "任务2"];
    let len = businessApi.handleList(arr);
    // JS对象配置参数
    let cfg = {time: "09:00"};
    let newCfg = businessApi.setConfig(cfg);
}

该能力大幅拓展脚本业务边界,自动化脚本可直接读取 App 本地数据库、调用原生网络接口、操作本地文件,实现纯脚本无法完成的复杂业务流程。

五、生产环境管控:生产 / 调试模式切换与设备信息读取

SDK 提供一组静态全局工具方法,用于线上环境管控、设备信息统计,无需 Activity 上下文即可调用:

  1. 模式切换:SAR.toggleProdMode() 静态方法切换调试 / 生产模式;调试模式开启日志、弹窗提示,生产模式屏蔽调试日志,提升运行效率;
  2. 模式判断:SAR.getProdMode() 返回布尔值,区分线上正式环境与本地调试;
  3. 设备标识:SAR.getDeviceName() 获取设备唯一名称,用于后台设备区分;
  4. 账号读取:SAR.getUsername(context) 获取当前登录账号,用于业务数据绑定、权限区分。

生产环境最佳实践:App 打包 Release 版本时默认开启 Prod 生产模式,屏蔽调试弹窗与冗余日志;仅内测包开放调试模式,便于线上问题排查。

六、登出与资源释放完整逻辑

用户退出登录、切换账号时调用 logout 方法,清空本地登录缓存、停止所有运行脚本、释放引擎占用资源,避免后台持续运行造成耗电、内存占用过高:

SAR.getInstance().logout(new LogoutListener() {
    @Override
    public void onLogoutResult(boolean success) {
        if (success) {
            // 登出成功,跳转登录页,清空本地业务缓存
        }
    }
});

登出后如需再次使用自动化能力,必须重新走 init→autoLogin/login 完整生命周期流程。

七、工程落地常见问题与优化方案

8.1 编译阶段报错:第三方依赖类找不到

问题现象:运行时报 netty、okhttp 类不存在;解决方案:核对 build.gradle 中三个底层依赖版本号与官方文档一致,禁止修改版本号;或切换 Fat AAR 包集成方案,省去手动依赖配置。

8.2 引擎 init 初始化失败,权限弹窗不弹出

问题现象:调用 init 后 onInitResult 返回 false,无权限提示;优化方案:StartupActivity 必须为前台可见 Activity,不能使用后台 Service 调用 init;适配 Android 12 + 权限适配,提前申请悬浮窗、无障碍基础权限,减少引擎校验失败概率。

8.3 脚本执行内存泄漏、后台持续耗电

优化方案:严格在 MainActivity 的 onDestroy 中调用 SDK 对应销毁方法;页面退出前主动停止正在运行的脚本;App 完全退出时执行 logout 释放引擎资源。

8.4 Java 与 JS 传参类型转换异常

问题现象:JS 传入数字、数组时报错;规范:JS 中数组统一使用 SDK 内置 JSArray、JSObject 接收,禁止直接使用原生 Java 数组、HashMap 接收,严格遵循文档定义数据类型映射规则。

八、总结

将冰狐智能辅助移动端 SDK 集成至自研 Android 应用,整体集成流程遵循 “引擎初始化→账号登录→页面生命周期绑定→脚本执行与双向交互→登出资源释放” 标准化流程,结合生产模式管控、全局状态监听、脚本多路径加载等能力,可快速搭建一套稳定、可管控、可拓展的内置自动化脚本引擎,为 Android 应用赋予原生自动化能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值