美文网首页
蓝牙重连专项总结

蓝牙重连专项总结

作者: 小蜗牛的成长 | 来源:发表于2018-02-23 16:18 被阅读0次

结合开源python版本的uiautomator

前言

   蓝牙重连专项中,涉及开关手机蓝牙、开关飞行模式、开关手机、超范围等场景,每一项执行次数5或者20次视情况而定,手工操作较繁琐,首先考虑脚本执行,以工具的形式进行辅助测试,节约人力和时间。

实现手段

   整个脚本使用python 语言,结合xiaocong用python封装的开源uiautomator。场景操作中,借助辅助app实现操作手机的部分控件,避免过多兼容性问题出现。

python版uiautomator简单说明
   版本信息:v0.3.2
   Github地址: https://github.com/xiaocong/uiautomator
   安装:pip install uiautomator
   已安装库,更新库:pip install --upgrade uiautomator

使用:
   设备操作

d.press.home()或者d.press("home”) 
d.press.back() 

   截图

d.screenshot()

   UI对象操作

#定位元素 
d(text='Clock', className='android.widget.TextView')#元素对象text为'Clock',className为=ndroid.widget.TextView 
#其他可用属性
  text
  textContains
  textMatches
  textStartsWith 
  className
  classNameMatches 
  description
  descriptionContains
  descriptionMatches
  descriptionStartsWith
  checkable
  checked
  clickable
  longClickable
  scrollable
  enabled
  focusable
  focused
  selected 
  packageName
  packageNameMatches
  resourceId
  resourceIdMatches
  index
  instance 

   延长等待或者直接判断元素是否存在

  # 等待timeout时长直到元素出现 
d(text="Settings").wait.exists(timeout=3000) 
  # 等待timeout时长,直到元素消失 
d(text="Settings").wait.gone(timeout=1000) 
  # 存在返回true,否则返回false 
d(text="Settings").exists 
d.exists(text="Settings") # alias of above property. 

Watcher 的使用

#当一个选择器找不到匹配的元素时才执行
d.watcher("AUTO_FC_WHEN_ANR").when(text="ANR").when(text="Wait") \
                             .click(text="Force Close")
d.watcher("AUTO_FC_WHEN_ANR").when(text="ANR").when(text="Wait") \
                             .press.back.home()

   以上仅列举常用的ui操作方法,完整的内容介绍需要查看github上的说明,不过可以肯定的是,uiautomator并不会包含所有方法,例如连续点击等,若有需求,则需要自行实现或者选择其他的开源框架,另外原作者未在维护,使用过程中会存在一定的问题,需要自己阅读源码稍加修改,下面我会就整个过程中遇到的问题做一个汇总。

实现过程中遇到的坑

  • 界面控件存在,但点击不中

精准定位和快速定位的问题
   借助调用一下dump(compressed=False)方法来间接的调setCompressedLayoutHeirarchy(compressed=False)
原方法解释

#setCompressedLayoutHeirarchy 
void setCompressedLayoutHeirarchy (boolean compressed) 
      Enables or disables layout hierarchy compression. If compression is enabled,
      the layout hierarchy derived from the Acessibility framework will only
      contain nodes that are important for uiautomator testing. Any unnecessary
      surrounding layout nodes that make viewing and searching the hierarchy
      inefficient are removed. 

   以上方法实现后,部分手机偶尔找不到控件,可通过按home键,切换其他界面,找寻控件时适当增加延时等方法实现,增加找寻控件的成功率

  • 部分手机老是弹安装uiautomator apk权限框,无法执行,或者rpc service can be restarted,或者运行过程中卡住

   例如:oppo、vivo系列手机在执行前或者执行中,老是弹安装uiautomator apk权限框,无法继续执行,相对来说,海外手机比国内手机在自动化执行时顺畅多了,没办法,权限嘛
   追溯该问题源头,见__init__.py文件中的该方法,当sdk 版本超过18时,需要安装app-uiautomator.apkapp-uiautomator-test.apk,那么问题来了,为什么需要安装这2个apk呢?
   有经验的人可知道,app-uiautomator.apkapp-uiautomator-test.apk是uiautomator 2.0的的辅助apk,查看了一下github,这2个文件也是后来人添加上去的,原作者的使用的是uiautomator 1.0,这里不好猜测后面人为什么添加,到目前为止,我是没有找到添加的理由,当然有知道的人可以告诉我,十分感谢。

 def start(self, timeout=5):
        if self.sdk_version() < 18:
            files = self.push()
            cmd = list(itertools.chain(
                ["shell", "uiautomator", "runtest"],
                files,
                ["-c", "com.github.uiautomatorstub.Stub"]
            ))
        else:
            self.install()
            cmd = ["shell", "am", "instrument", "-w",
                    "com.github.uiautomator.test/android.support.test.runner.AndroidJUnitRunner"]

        self.uiautomator_process = self.adb.cmd(*cmd)
        self.adb.forward(self.local_port, self.device_port)

解决方案:

   在__init__.py文件中

  1. stop()方法中,增加卸载jar包的方法,见后续代码
  2. start()方法中去掉else流程,我是直接将if self.sdk_version() < 18:更改为if True or self.sdk_version() < 18:
  def stop(self):
        '''Stop the rpc server.'''
        if self.uiautomator_process and self.uiautomator_process.poll() is None:
            res = None
            try:
                res = urllib2.urlopen(self.stop_uri)
                print("res={}".format(res))
                self.uiautomator_process.wait()
            except:
                self.uiautomator_process.kill()
            finally:
                if res is not None:
                    res.close()
                self.uiautomator_process = None
        try:
            print("find uiautomator ps ? ")
            out = self.adb.cmd("shell", "ps", "-C", "uiautomator").communicate()[0].decode("utf-8").strip().splitlines()
            if out:
                index = out[0].split().index("PID")
                for line in out[1:]:
                    if len(line.split()) > index:
                        print(line.split()[index])
                        self.adb.cmd("shell", "kill", "-9", line.split()[index]).wait()
            print("stop()后,新增执行卸载")
            package_names = ["com.github.uiautomator","com.github.uiautomator.test"]
            for pkg in package_names:#新增
                self.adb.cmd("uninstall", pkg).wait()
        except:
            pass
  • 多线程调用Subprocess.popen()时,提示win报错: if _WaitForSingleObject(self._handle, 0) == _WAIT_OBJECT_0: OSError: [WinError 6] 句柄无效

解决方案:
   window系统电脑, 注释掉subprocess.py中的 _cleanup()方法
原文解释

When Popen is called it does some internal cleanup via the _cleanup function, which checks to see if any
deleted Popen instances are still running and tries to wait on them and get the exit status. This is really only
required on Unix systems to avoid zombies. On Windows it suffices to let the Popen instance get 
collected which in turn collects the Handle instance for the process handle, which calls CloseHandle, 
and that's it. If the handle is invalid, that's weird and shouldn't happen, but it's an error we could ignore on
Windows.When Popen is called it does some internal cleanup via the _cleanup function, which checks to
see if any deleted Popen instances are still running and tries to wait on them and get the exit status. This is
really only required on Unix systems to avoid zombies. On Windows it suffices to let the Popen instance get
collected which in turn collects the Handle instance for the process handle, which calls CloseHandle, and
that's it. If the handle is invalid, that's weird and shouldn't happen, but it's an error we could ignore on Windows. 
  • 部分手机在执行完毕等待期间会锁屏,影响下一次ui操作

   借助adb命令辅助判断手机屏幕状态,可通过以下命令

dumpsys window policy|findstr isStatusBarKeyguard #若是linux系统,则用grep
dumpsys window policy|findstr mShowingLockscreen

可封装成

#解锁状态isStatusBarKeyguard和mShowingLockscreen_status均为false
def  get_device_lock_status(self):
                _,isStatusBarKeyguard=self.shell("dumpsys window policy|{} isStatusBarKeyguard".format(self.__find))
                isStatusBarKeyguard_status=re.findall(r"(?<=isStatusBarKeyguard=)(\w+)",isStatusBarKeyguard)
    
                _,mShowingLockscreen=self.shell("dumpsys window policy|{} mShowingLockscreen".format(self.__find))
                mShowingLockscreen_status=re.findall(r"(?<=mShowingLockscreen=)(\w+)",mShowingLockscreen)
     
                if isStatusBarKeyguard_status and mShowingLockscreen_status:
                  return (ast.literal_eval(isStatusBarKeyguard_status[0].capitalize()) or ast.literal_eval(mShowingLockscreen_status[0].capitalize()))

                elif isStatusBarKeyguard_status:
                  return ast.literal_eval(isStatusBarKeyguard_status[0].capitalize())

                else:
                  return ast.literal_eval(mShowingLockscreen_status[0].capitalize())
  • 部分手机执行报错:uiautomator.JsonRPCError: JsonRPC Error code: 0, Message: java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permissio

   例如:红米note2 ,手机特性,允许通过usb安装及usb调试需要有SIM卡才能打开,否则无法安装

结束语

   每一次实践都是一次修行,认真思考、认真总结

相关文章

  • 蓝牙重连专项总结

    结合开源python版本的uiautomator 前言 蓝牙重连专项中,涉及开关手机蓝牙、开关飞行模式、开关手...

  • 蓝牙断线重连

    http://www.cocoachina.com/bbs/read.php?tid-1722597.html

  • iOS 蓝牙开发

    不想写太多字、所以就直接粘贴代码了1、实现蓝牙单连接2、实现蓝牙重连3、实现蓝牙简单发送指令 这个Demo是16年...

  • iOS-蓝牙-后台重连

    简单记录一下:前提条件是已经可以在后台时收发蓝牙数据。在后台断开连接时,程序确实调用了: 但是一直无法扫描到我需要...

  • Flutter_Blue插件使用,断开重连发送命令报错

    在使用flutter_blue插件开发蓝牙功能,遇到一个问题就是,断开蓝牙,然后重连,会报错,而且发送命令会失败,...

  • 30分钟学会写安全生产专项工作总结和汇报

    安全生产专项工作总结,是指建筑施工、矿山、交通、危化品、烟花爆竹等专项工作总结。这些专项性较强、时效性明显的...

  • android蓝牙专题

    深入了解Android蓝牙Bluetooth ——《总结篇》 安卓蓝牙应用程序编写步骤 蓝牙 bluetooth-...

  • 微信小程序蓝牙开发总结

    接口总结 正常使用: 初始化(开启)蓝牙模块wx.openBluetoothAdapter 搜索蓝牙设备(消耗大量...

  • Socket 知识点总结复习

    Socket 知识总结 1.socket 概念 通讯流程: 2.socket 断开重连 socket 的KeepA...

  • 雷柏鼠标蓝牙4.0模式断开重连问题

    系统:win10 Home版 鼠标:雷柏M500 2.4G蓝牙双模鼠标 开启蓝牙配对可以搜索到两个鼠标,如下图,两...

网友评论

      本文标题:蓝牙重连专项总结

      本文链接:https://www.haomeiwen.com/subject/nfypuxtx.html