数据保护背景下,安全团队引入了哪些新技术进行防控升级?点击学习案例 了解详情
写点什么

Android 自动化交互实践

  • 2020 年 11 月 28 日
  • 本文字数:2880 字

    阅读完需:约 9 分钟

Android 自动化交互实践

Android 自动化交互可以代替人工完成重复性的工作,包括通过自动操作 App 进行黑盒测试和第三方 App 的自动运行。常见的自动化交互包含启动 App、view 的点击、拖拽和文本输入等。随着 App 安防能力的提升,要想实现完整流程的自动化交互变的越来越困难,本文主要探讨目前常见的自动化交互方案以及不同方案的优劣和应用场景。


1 传统执行脚本方案


ADB 是 Google 提供的能够和 Android 设备进行交互的命令行工具,我们可以编写脚本按照事先设计好的顺序,一个一个执行各个事件。ADB 执行操作需要事先获取界面元素的坐标(获取坐标方法可以利用 uiautomator 或者 dump xml 的方法,这里不是讨论的重点),然后把坐标传入作为命令行参数。


adb shell input tap 100 500
复制代码


上面命令是模拟点击屏幕坐标为(100, 500)处的控件。


adb shell input swipe 100 500 200 600
复制代码


上面命令是模拟手指在屏幕上向右下方滑动的一个操作。


adb shell input keyevent "KEYCODE_BACK"
复制代码


上面命令模拟返回按键的点击。


一次完整的自动化交互流程可由上面一系列命令顺序执行。


ADB 脚本方式的优点


  1. 实现简单,只需要获取目标元素的坐标等简单信息即可完成相关操作

  2. 可以实现对 webview 的自动化交互


ADB 脚本方式的缺点


  1. 灵活度不够,依赖于写死的坐标,App 界面变更引起的 view 位置变换会让脚本中相关命令无法执行,需要重新分析页面坐标

  2. 需要建立 ADB 链接或套接字链接,交互过程中网络状况的变化会影响自动化交互效果


ADB 脚本方式应用场景


  1. 交互简单、迭代频率低,安防级别比较低的 App

  2. webview 页面,flutter 开发的 App


2 Android 原生方法实现自动化交互


我们可以借助各种插件化框架来控制 App 页面的界面元素,其中一种思路就是在插件中借助 ActivityLifecycleCallbacks 来监听各个 activity 的生命周期。


public class MyApplication extends Application {    private static final String TAG = "MyApplication";    //声明一个监听Activity们生命周期的接口    private ActivityLifecycleCallbacks activityLifecycleCallbacks = new ActivityLifecycleCallbacks() {        /**         * application下的每个Activity声明周期改变时,都会触发以下的函数。         */        @Override        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {            //如何区别参数中activity代表你写的哪个activity。            if (activity.getClass() == MainActivity.class)                Log.d(TAG, "MainActivityCreated.");            else if(activity.getClass()== SecondActivity.class)                Log.d(TAG, "SecondActivityCreated.");        }
@Override public void onActivityStarted(Activity activity) { Log.d(TAG, "onActivityStarted."); }
@Override public void onActivityResumed(Activity activity) { Log.d(TAG, "onActivityResumed."); }
@Override public void onActivityPaused(Activity activity) { Log.d(TAG, "onActivityPaused."); }
@Override public void onActivityStopped(Activity activity) { Log.d(TAG, "onActivityStopped."); }
@Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { }
@Override public void onActivityDestroyed(Activity activity) { Log.d(TAG, "onActivityDestroyed."); } };
@Override public void onCreate() { super.onCreate(); //注册自己的Activity的生命周期回调接口。![Alt text](./WechatIMG59.png)
registerActivityLifecycleCallbacks(activityLifecycleCallbacks); }
@Override public void onTerminate() { //注销这个接口。 unregisterActivityLifecycleCallbacks(activityLifecycleCallbacks); super.onTerminate(); }}
复制代码


监听到 activity 的活动后,可以借助 uiautomator 分析 activity 界面元素的 viewId 以及属性,不同情况的界面 view 可以采用不同的自动化方法。


2.1 简单 view 的处理方式


如下图:



像这类 view,可以直接获取到 resource id ,并且确认可点击属性为 true,操作方式比较简单, 可以在监听到的 activity 生命周期中执行如下操作:


int fl_btn = activity.getResources().getIdentifier("dashboard_title",         "id", "com.android.settings");View v =  activity.findViewById(fl_btn);
v.performClick();
复制代码


2.2 隐藏属性的 view 的处理方式


在一些对 view 的属性进行隐藏,特别是利用 React Native 等混合开发的页面,上面的方法不再生效,如下图所示的 view:



如图,选中的 viewgroup 及其子 view 的 clickable 属性均为 false,并且无法获取到 view 的 resource id,这时候可以利用图中 dump 出的布局信息,借助 Xpath 元素定位工具来获取到界面的 view,由于这些 view 的点击属性为 false,因此通过调用 performClick 来实现点击的方法已经无效,此时考虑在 click 更底层的与触摸事件传递相关的比较重要的类:MotionEvent, MotionEvent 可以仿真几乎所有的交互事件,包括点击,滑动,双指操作等。以单击为例:


    private void simulateClick(View view, float x, float y) {        long time = SystemClock.uptimeMillis();//必须是 SystemClock.uptimeMillis()。
MotionEvent downEvent = MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, x, y, 0);
time += 500;
MotionEvent upEvent = MotionEvent.obtain(time, time, MotionEvent.ACTION_UP, x, y, 0);
view.onTouchEvent(downEvent); view.onTouchEvent(upEvent); }
复制代码


如果是滑动操作,可以在起始位置中间添加若干 ACTION_MOVE 类型的 MotionEvent. 综上所述,借助系统原生方法时间交互自动化的优缺点大致如下:


借助插件框架实现自动化交互的优点


  1. 可维护性强,因为可以直接获取到界面的 view 对象,因此即使页面布局发生变化,只要 view 还存在,就不需要对代码进行修改

  2. 仿真效果更好,比脚本方式更接近真人操作


借助插件框架实现自动化交互的不足


  1. 对 webview、flutter 框架 App 支持不好


应用场景


  1. 版本迭代频繁的 App

  2. 非 flutter 框架开发的 App


上面分析了两种常用的模拟真实用户进行自动化操作的方法,脚本方式和调用原生方法的方式,这两种方法基本上可以完成简单的交互流程,在此基础上,我们还可以去深究一些更深层次的交互实现,比如自动化过各种验证等,也可以基于这两种方法来完成。


作者介绍


李涛,2015 年 3 月加入去哪儿网,客户端开发工程师,曾经担任酒店业务和自助入离机项目开发。现负责国际酒店抓取系统开发与维护。


本文转载自公众号 Qunar 技术沙龙(ID:QunarTL)。


原文链接


Android 自动化交互实践


2020 年 11 月 28 日 16:251247

评论

发布
暂无评论
发现更多内容

助车企升级,旺链科技与南方电网、联想等名企同斩获「创新案例奖」

旺链科技

区块链 产业区块链 供应链金融

☕【权限设计系列】「认证授权专题」微服务架构的登陆认证问题

浩宇天尚

微服务架构 12月日更 权限认证机制 授权设计

域名基本信息查询小技巧

喀拉峻

网络安全 安全 信息安全

千万级日志回放引擎设计稿

FunTester

性能测试 测试框架 FunTester 流量回放 GOREPLAY

一次完整的渗透测试&仅供学习研究

H

黑客 网络安全 渗透测试·

基于磁盘量身定制,十亿规模高效向量检索方案

Zilliz

向量检索 anns 向量计算

人工智能(NLP)|社交网络中的网络表示学习技术研究

索信达控股

人工智能 算法 网络结构

在线JSON转PHP Array工具

入门小站

工具

架构训练营模块三作业

zhongwy

架构实战营 「架构实战营」

揭秘字节跳动基于Hudi的实时数据湖平台

字节跳动数据平台

大数据 实时数据湖

【转】大数据开发之Spark面试八股文

@零度

大数据 spark

通过一个实际例子理解Kubernetes里pod的自动scale - 水平自动伸缩

Jerry Wang

Kubernetes k8s 28天写作 docker build 12月日更

Spring框架基础知识(03)

海拥(haiyong.site)

28天写作 12月日更

实现一键部署与高效集群管理,SphereEx-Boot 正式上线

SphereEx

开源 开源社区 SphereEx ShadingSphere 一键安装

HDFS源码解析:教你用HDFS客户端写数据

华为云开发者联盟

hdfs block appendChunk

技术“开源”对于金融业软件发展的影响

Speedoooo

安全 ios开发 APP开发 Andriod开发 小程序容器

面试官:方法重写时需要注意哪些问题?

王磊

恒源云(GPUSHARE)_云GPU服务器如何使用SpaCy?

恒源云

gpu 服务器 自然语言

60 K8S之EFK日志管理系统

穿过生命散发芬芳

k8s 28天写作 12月日更

How old are you | 尚硅谷大数据之Canal视频教程

编程江湖

大数据 canal

Dubbo 框架学习笔记十七

六维

dubbo 12月日更

一文带你了解数据库安全基础

坚果

数据库 28天写作 12月日更

带你认识三种kafka消息发送模式

华为云开发者联盟

kafka 时间 异步 消息发送 producer

尚硅谷大数据之Canal视频教程发布!

@零度

大数据

使用亚马逊云科技DevOps 工具构建 InnerSource 生态系统

亚马逊云科技 (Amazon Web Services)

开源 InnerSource

seata分布式事务AT模式介绍(二)

恒生LIGHT云社区

分布式 分布式事务 seata

网易有道项目实践技术分享合集

有道技术团队

技术分享 网易有道 技术专题合集

4k/8k超高清时代,如何利用媒体处理技术加速数字化升级

4k/8k超高清时代,如何利用媒体处理技术加速数字化升级

Android 自动化交互实践_测试_Qunar技术沙龙_InfoQ精选文章