05-对混合app应用中的元素进行定位

        本文介绍对于混合app应用中的元素如何进行定位。

一、app的类型

1)Native App(原生应用)

        原生应用是指利用Android、IOS平台官方的开发语言、开发类库、工具等进行开发的app应用,在应用性能和交互体验上应该是最好的。

        通俗点来讲,原生开发就像盖房子一样,先打地基然后浇地梁、房屋结构、一砖一瓦、钢筋水泥、电路走向等,都是经过精心的设计。原生app也一样:将每个页面、每个功能、每个效果、每个逻辑、每个步骤全部用代码一层层、一段段的写出来。

优点:

  • 可访问手机所有功能、可实现功能最齐全。
  • 运行速度快、性能高,绝佳的用户体验。
  • 支持大量图形和动画。不卡,反应快。
  • 比较快捷地使用设备端提供的接口,处理速度上有优势。

缺点:

  • 在过去主要是成本高、周期长,Android和iOS都需要单独开发。
  • 更新版本需要重新下载安装包。        
2)Web App(Web版应用)

        Web版应用是利用Web技术进行开发的,通过浏览器进行访问。Web版应用需要浏览器的支持才能进行展示和用户交互,因此主要用到的技术是HTML5、Javascript、CSS等。HTML5支持一些新标签和脚本,可以做出类似原生应用的效果和动画。

优势:

  • 支持范围广。
  • 开发成本低、周期短。

缺点:

  • 对联网要求高,离线不能做任何操作。
  • 功能有限。
  • 运行速度慢,页面不能承载太多东西。
  • 图片和动画支持性不高。
  • 如果用户使用更多的新型浏览器,那么运行过程中容易出现问题。
3)Hybrid App(混合应用)

        混合应用是利用了原生app的开发技术和HTML5技术进行开发的app应用,是原生和HTML5技术的混合应用,混合比例不限。

        混合开发是一种取长补短的开发模式,原生代码中利用Web View插件或者其它框架为H5提供容器,程序主要的业务实现、界面展示都是利用与H5相关的Web技术进行实现的。比如京东、淘宝、今日头条等app都是利用混合开发模式而成的。

优点:

  • 开发周期短。
  • 功能更新发布快。

缺点:

  • 用户体验不如原生应用。
  • 性能稍慢(需要连接网络)。

二、webview的概述

        现在大部分app都是混合式的native+webview,对于native上的元素通过uiautomatorviewer很容易定位到,而对于webview上的元素就无法识别了。

1)什么是webview?

        WebView直译是网页视图,是一个基于webkit内核的,用于显示网页的控件,具备渲染Web页面的功能。Android的Webview在低版本和高版本采用了不同的webkit版本内核,4.4后直接使用了Chrome浏览器的内核。

        WebView可以将Web网页内嵌在移动端,实现前端的混合式开发,大多数混合式开发框架都是基于WebView模式进行二次开发的,比如:uni-app、Hybrid app等。

2)webview的作用
  • 显示和渲染Web页面。
  • 直接使用html文件(网络上或本地assets中)作布局。
  • 可以和JavaScript交互调用。

        WebView控件功能强大,除了具有一般View的属性和设置外,还可以对url请求、页面加载、渲染、页面交互进行强大的处理。

3)webview的优点
  • 一次开发,多系统适配,节省人力成本和时间成本。

        用H5开发的页面内容可以跨平台使用。无论你用的安卓还是苹果,你的淘宝app里都是H5页面。也就是一次开发,多系统适配,是不是节省了人力成本和时间成本?

        如果不用混合开发这种方式,就得找安卓工程师开发安卓端的、苹果IOS工程师开发苹果的,需要开发两次,是不是很麻烦?

  • Web更新方式为线上即时更新,不用下载安装补丁包。

        你想想,你玩王者或吃鸡吗?这些游戏里的游戏内容都是原生开发的,每次更新你都得先下载安装包吧?当然,打开游戏经常会有一些类似活动公告、说明公告等一些窗口,这些可能也是由WebView嵌入的Web页面。也就是说,原生app里嵌入的Web内容所占比例可大可小,根据需求,对于适合WebView的模块,我们就可以选择用WebView实现它。

        而WebView中嵌入的网页更新需要下载安装包吗?更新后的内容即时上线,根本不需要下载安装包,这样对于用户来讲就很舒服。

  • H5性能不断提高。

  实际上,H5页面的交互、渲染性能肯定是比不上原生的。但随着H5技术的加快发展,加上5G网络的普及化,性能这一块就逐渐不再成问题了。典型的案例就是电商类app应用,性能差距基本看不出来,用户体验还是很舒服的。

        当然,像游戏这类应用,牵扯到渲染引擎性能的问题,对于这点,Web渲染引擎还是不太够用的,对比安卓原生或IOS原生应用,效果太差。

三、识别webview

        用uiautomatorviewer定位工具查看页面,发现页面上有些区域是无法定位到的,如下图左边红色区域,只能定位到这个大红框,红框里面的元素是无法识别的。

        查看该红色框的属性,它的class属性值为WebView,那毫无疑问这种页面就是webview了。

四、获取contexts

        contexts是上下文环境,类似于selenium中的句柄(handle),用于区分不同的环境。

        获取应用当前显示页面的contexts上下文,如下图红框内容所示,获取到的是一个list列表:

  • NATIVE_APP:这个就是native。
  • WEBVIEW_com.xxxx:这个就是webview。

        当看到这样的打印结果,就说明获取到了webview的上下文了(当然有的app有坑,明明有webview,却通过contexts获取不到, 那是开发没打开webview调试)。

from appium import webdriver
import time# 设置启动参数
desired_cap = {}
desired_cap['platformName'] = 'Android'
desired_cap['platformVersion'] = '6.0.1'
desired_cap['deviceName'] = '127.0.0.1:7555'
# 必须参数,指定被测软件的包名
desired_cap['appPackage'] = 'com.android.browser'
# 必须参数,指定要打开app的哪个页面
desired_cap['appActivity'] = '.BrowserActivity'
desired_cap['automationName']='Uiautomator2'
desired_cap['noReset'] = True
desired_cap['newCommandTimeout'] = 6000
desired_cap['unicodeKeyboard'] = True
desired_cap['resetKeyboard'] = Truedriver = webdriver.Remote('http://localhost:4723/wd/hub', desired_cap)
time.sleep(5)# 获取当前页面所有的上下文环境
print(driver.contexts)

五、从native切换到webview

        要想操作webview上的元素,第一步需要切换环境(与selenium中切换iframe、切换handle思路是一样的)。

        切换方法是:switch_to.context(参数是webview的上下文)

        根据上述打印结果可知,获取到contexts是一个list列表对象,所以这里取这个列表中的第二个参数即可,也就是contexts[1]。

from appium import webdriver
import time# 设置启动参数
desired_cap = {}
desired_cap['platformName'] = 'Android'
desired_cap['platformVersion'] = '6.0.1'
desired_cap['deviceName'] = '127.0.0.1:7555'
# 必须参数,指定被测软件的包名
desired_cap['appPackage'] = 'com.android.browser'
# 必须参数,指定要打开app的哪个页面
desired_cap['appActivity'] = '.BrowserActivity'
desired_cap['automationName']='Uiautomator2'
desired_cap['noReset'] = True
desired_cap['newCommandTimeout'] = 6000
desired_cap['unicodeKeyboard'] = True
desired_cap['resetKeyboard'] = Truedriver = webdriver.Remote('http://localhost:4723/wd/hub', desired_cap)
time.sleep(5)# 1.获取当前页面所有的上下文环境
all_context = driver.contexts
print(all_context)# 2.从native切换到webview
driver.switch_to.context(all_context[1])# 3.打印当前的上下文环境,查看是否切换成功
print(driver.current_context)
1)报错分析

        执行上面程序,报错:Unable to automate Chrome version because it is too old for this version of Chromedriver.

        Android的webview使用的是chrome浏览器的内核,这里的报错是说webview的chrome版本号和chromedriver驱动的版本号不匹配。

2)解决办法
  • 首先,查看webview的chrome版本号是多少?

        在电脑chrome浏览器中输入:chrome://inspect/#devices,点开手机设备的浏览器,随便打开一个网页,点击电脑chrome浏览器的刷新按钮,就会出现webview的chrome版本号信息。

  • 然后,下载chrome版本号相对应的chromedriver驱动。

        找到webview的chrome版本号之后,下载对应的chromedriver驱动就可以了。下载地址:chromedriver.storage.googleapis.com/index.html。

  • 最后,将不匹配的chromedriver驱动进行替换。

3)执行结果

        解决报错之后,重新执行代码,执行结果如下:

六、从webview切换到native

        在webview上操作完之后,想返回到native上操作,这时候需要先切回来,切回native有两个方法:

  • driver.switch_to.context("NATIVE_APP") # 这个NATIVE_APP是固定的参数
  • driver.switch_to.context(contexts[0])        # 从contexts列表中取第一个参数
from appium import webdriver
import time# 设置启动参数
desired_cap = {}
desired_cap['platformName'] = 'Android'
desired_cap['platformVersion'] = '6.0.1'
desired_cap['deviceName'] = '127.0.0.1:7555'
# 必须参数,指定被测软件的包名
desired_cap['appPackage'] = 'com.android.browser'
# 必须参数,指定要打开app的哪个页面
desired_cap['appActivity'] = '.BrowserActivity'
desired_cap['automationName']='Uiautomator2'
desired_cap['noReset'] = True
desired_cap['newCommandTimeout'] = 6000
desired_cap['unicodeKeyboard'] = True
desired_cap['resetKeyboard'] = Truedriver = webdriver.Remote('http://localhost:4723/wd/hub', desired_cap)
time.sleep(5)# 1.获取当前页面所有的上下文环境
all_context = driver.contexts
print(all_context)# 2.从native切换到webview
driver.switch_to.context(all_context[1])# 3.打印当前的上下文环境,查看是否已切换到webview
print(driver.current_context)# 4.从webview切换到native
driver.switch_to.context(all_context[0])# 5.打印当前的上下文环境,查看是否已切换回native
print(driver.current_context)

七、使用DevTools工具对webview上的元素进行定位

        app应用中webview内嵌的页面是基于chrome浏览器的内核加载的,在电脑上的chrome浏览器中有个开发者调试工具DevTools,可以很方便的对webview上的元素进行定位。

1)启动DevTools工具
  1. 电脑上打开chrome浏览器,输入:chrome://inspect/#devices。
  2. Discover USB devices 这个要勾选的,可以检测到手机设备。
  3. Discover network targets 这个要勾选的,可以检测到网络。
  4. 下图箭头指向的,是手机的设备名称。
  5. WebView in com.android.browser (91.0.4472.114) 这个是手机浏览器中的chrome内核版本号。

2)定位元素

        上图红框中的地址就是电脑chrome浏览器加载到的手机设备中webview的网页地址,点击地址下的inspect按钮,进入调试界面。

        接下来的元素定位就跟selenium的定位是一回事了。

3)示例代码

        这里首先定位webview中的百度搜索输入框,然后输入内容,最后点击 “百度一下” 按钮。

from appium import webdriver
import time# 设置启动参数
desired_cap = {}
desired_cap['platformName'] = 'Android'
desired_cap['platformVersion'] = '6.0.1'
desired_cap['deviceName'] = '127.0.0.1:7555'
# 必须参数,指定被测软件的包名
desired_cap['appPackage'] = 'com.android.browser'
# 必须参数,指定要打开app的哪个页面
desired_cap['appActivity'] = '.BrowserActivity'
desired_cap['automationName']='Uiautomator2'
desired_cap['noReset'] = True
desired_cap['newCommandTimeout'] = 6000
desired_cap['unicodeKeyboard'] = True
desired_cap['resetKeyboard'] = Truedriver = webdriver.Remote('http://localhost:4723/wd/hub', desired_cap)
time.sleep(5)# 1.获取当前页面所有的上下文环境
all_context = driver.contexts
print(all_context)# 2.从native切换到webview
driver.switch_to.context(all_context[1])# 3.打印当前的上下文环境,查看是否已切换到webview
print(driver.current_context)# 4.定位输入框后,输入内容,并进行搜索
driver.find_element('id', 'index-kw').clear()
driver.find_element('id', 'index-kw').send_keys('python')
driver.find_element('id', 'index-bn').click()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/30354.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Win10录屏,3种方法,快速搞定

在数字化时代,录屏功能已经成为了我们日常生活和工作中不可或缺的一部分。无论是为了制作教学视频,还是为了记录游戏的高光时刻,还是为了保存开会内容,录屏功能都能为我们提供极大的便利。Win10操作系统作为微软推出的经典之作&am…

在k8s中部署Elasticsearch高可用集群详细教程

🐇明明跟你说过:个人主页 🏅个人专栏:《洞察之眼:ELK监控与可视化》🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、Elasticsearch简介 2、为什么在k8s中部署elasti…

Redis 6.0新特性详解

Redis 6.0新特性主要有3个:多线程、Client Side Cache、Acls。下面详细说明一下。 1.多线程 redis 6.0 提供了多线程的支持,redis 6 以前的版本,严格来说也是多线程,只不过执行用户命令的请求时单线程模型,还有一些线…

鸿蒙HarmonyOS实战:状态管理和传值

状态管理 State State是一个装饰器,是用来存放数据的,比较好理解 由State的数据来进行状态驱动视图更新 代码很简单 State count: number 0; 需要注意的是State初始化的数据必须赋值 这里我们讨论简单用法,至于复杂的用法可以到项目中介绍…

RAG 流程及论文串烧

文档切片 文档切片的五个层次 https://medium.com/anuragmishra_27746/five-levels-of-chunking-strategies-in-rag-notes-from-gregs-video-7b735895694d#b123 Basic RAG 与 Advanced RAG https://pub.towardsai.net/advanced-rag-techniques-an-illustrated-overview-04d…

Python学习笔记14:进阶篇(三)。类的终结篇,类的导入和模块的导入。

前言 这篇文章属于类知识的最后一篇,带一点点其他知识,学习内容来自于Python crash course。 关注我私信发送Python crash course,分享一份中文版PDF。 类的导入 在学习的时候,包括之前,我都是在一个文件中把所有代…

免费域名第二弹:手把手教你获取个性化免费域名并托管至Cloudflare

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 免费申请域名的方法 📒📝 注册账号📝 创建免费域名📝 将域名添加到 Cloudflare⚓️ 相关链接 ⚓️📖 介绍 📖 在如今的数字时代,拥有一个个性化的域名已经成为越来越多人的需求。无论是建立个人博客、项目展示,还…

鸿蒙开发通信与连接:【@ohos.connectedTag (有源标签)】

有源标签 说明: 本模块首批接口从API version 8开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 导入模块 import connectedTag from ohos.connectedTag;connectedTag.init init(): boolean 初始化有源标签芯片。 需要权限&#…

MySQL经典面试题:谈一谈你对事务的理解

文章目录 📑事务事务的基本概念回滚开启事务的sql语句 事务的基本特性总结一下涉及到的三个问题 ☁️结语 📑事务 事务的基本概念 事务是用来解决一类特定场景的问题的,在有些场景中,完成某个操作,需要多个sql配合完…

CPN IDE实现分层效果

Shift键鼠标选中要分层的库所和变迁!然后create subpage。 Subpage是这样的,不会像CPN tools里面自动生成IN和OUT库所,但是也能正确运行。 虽然父页面在运行中有标红:"port not defined" 错误通常意味着在模型中有一些连…

【QT5】<重点> QT多线程

文章目录 前言 一、QThread创建多线程 二、QMutex基于互斥量的同步 三、QReadWriteLock线程同步 四、QWaitCondition线程同步 五、QSemaphore基于信号量的同步 前言 本篇记录学习QT多线程的知识,参考视频13.1QThread创建多线程程序_哔哩哔哩。若涉及版权问题…

单元测试很难么?

前言 你可能会用单元测试框架,python的unittest、pytest,Java的Junit、testNG等。 那么你会做单元测试么!当然了,这有什么难的? test_demo.py def inc(x): return x 1 def test_answer(): assert inc(3) 4 i…

经验分享,CRC(循环冗余校验)在线计算

这里分享一个好用的在线计算CRC的网站。 网址:http://www.ip33.com/crc.html 截图:

Ubuntu22.04系统安装及配置

文章目录 一、选择“安装” 二、选择“语言” 三、安装器更新 四、键盘布局 五、选择安装类型 六、网络配置 七、代理设置 八、镜像地址 九、磁盘划分 十、设置用户名、主机名、登录密码 十一、升级到Ubuntu Pro 十二、SSH设置 十三、选装软件包 十四、开始安装进…

灰度图像直方图均衡化

文章目录 1.实验目的2.需求3.代码4.实验结果 1.实验目的 了解一种最基本的图像增强技术,本质上是对灰度图像进行灰度变换。 2.需求 对给定图像进行灰度直方图展示,然后均衡化后再次展示 3.代码 import cv2 as cv import numpy as np from matplotli…

类注释规范

类注释规范 1.1.1 模板配置 模板路径:File–>settings–>Editor–>File and Code Templates–>Includes–>File Header  N A M E :设置类名,与下面的 {NAME}:设置类名,与下面的 NAME:设…

【TB作品】MSP430G2553,单片机,口袋板, 多路温度巡回检测仪的设计

题7 多路温度巡回检测仪的设计 设计一个多路温度检测仪,共有8个测温点,每个点连续检测8次,以平均值代表该点温度,并轮流在LED显示器上显示。测试检测元件为铂热电阻Pt1000, 温度测量范围为100℃ ——500℃,测量精度为1…

Pointnet++改进即插即用系列:全网首发HeatBlock高计算效率和全局接受野|即插即用,提升特征提取模块性能

简介:1.该教程提供大量的首发改进的方式,降低上手难度,多种结构改进,助力寻找创新点!2.本篇文章对Pointnet++特征提取模块进行改进,加入HeatBlock,提升性能。3.专栏持续更新,紧随最新的研究内容。 目录 1.理论介绍 2.修改步骤 2.1 步骤一 2.2 步骤二 2.3 步骤三 1.…

Jlink下载固件到RAM区

Jlink下载固件到RAM区 准备批处理搜索exe批处理调用jlink批处理准备jlink脚本 调用执行 环境:J-Flash V7.96g 平台:arm cortex-m3 准备批处理 搜索exe批处理 find_file.bat echo off:: 自动识别脚本名和路径 set "SCRIPT_DIR%~dp0" set &qu…

【0008day】Shiny的介绍

介绍&#xff1a;Shiny 是一个开源 R 包&#xff0c;它提供了一个优雅而强大的 Web 框架&#xff0c;用于使用 R 构建 Web 应用程序。Shiny 可以帮助您将分析转变为交互式 Web 应用程序&#xff0c;而无需 HTML、CSS 或 JavaScript 知识。 # download R package pkgtest <-…