Python Python3 多线程解决安装权限弹窗

xiaoxiao · June 22, 2019 · Last by cccSummary replied at July 11, 2019 · 674 hits

上篇:https://testerhome.com/topics/19286, 只是启动了线程,在实际项目需要中,可能需要在执行完case之后,停掉所有启动的线程。然而,Python对线程的停止并不是那么友好。那么有什么方法可以更方便地达到此目的呢?经过一些尝试,发现可以通过设置标志位变量来进行操作。以下的例子中,因为涉及到多个py类文件,所以这个标志位就需要设置成全局变量。

1、新建thread_deal_permission_box.py,用于点掉手机设备的相关弹窗,代码如下:

import threading
from global_parameters import GlobalParameters
# 注意:
# 如果本机未安装u2,需要先安装,命令行执行以下命令:
# pip3 install uiautomator2 # 安装u2
# python3 -m uiautomator2 init # 手机自动安装atx, u2APK
# pip3 install --pre -U weditor # 安装UI查看器
# python3 -m weditor # 启动UI查看器
import uiautomator2 as u2
driver = u2.connect("882QADT9UWT")
global_parameters = GlobalParameters()

class ThreadDealPermissionBox(threading.Thread):

def __init__(self, driver):
threading.Thread.__init__(self)
self.driver = driver

def terminate(self):
global_parameters.set_value('_flag', True)

def run(self): # 把要执行的代码写到run函数里面 线程在创建后会直接运行run函数
while True:
self.click_permission_box()
print('Flag:' + str(global_parameters.get_value('_flag')))
if global_parameters.get_value('_flag'):
break

# 处理掉安装apk时的系统弹窗
def click_permission_box(self):
try:
self.driver(text="允许").click_exists(timeout=1.0)
except:
pass
try:
self.driver(text="确认").click_exists(timeout=1.0)
except:
pass
try:
self.driver(text="继续安装").click_exists(timeout=1.0)
except:
pass
try:
self.driver(text="安装").click_exists(timeout=1.0)
except:
pass

2、新建execute.py,封装执行adb shell的方法,代码如下:

import subprocess

class Execute():

# 执行shell
def shell(self, cmd):
# 执行cmd命令,如果成功,返回(0, 'xxx');如果失败,返回(1, 'xxx')
cmd_result = subprocess.getstatusoutput(cmd)
# print(str(cmd_result))
exit_code = cmd_result[0]
output = cmd_result[1]
if exit_code == 0:
if 'error' in output:
print('Maybe something wrong: ' + str(cmd_result))
return output
elif exit_code == 1:
print("Failed to execute cmd: " + cmd)
return output

3、新建adb_completely_install.py,用于安装apk应用,代码如下:

from execute import Execute
import os
import time
import threading
# 注意:
# 如果本机未安装u2,需要先安装,命令行执行以下命令:
# pip3 install uiautomator2 # 安装u2
# python3 -m uiautomator2 init # 手机自动安装atx, u2APK
# pip3 install --pre -U weditor # 安装UI查看器
# python3 -m weditor # 启动UI查看器
# import uiautomator2 as u2

execute = Execute()
# driver = u2.connect("882QADT9UWT")

# class AdbInstall():
class AdbCompletelyInstall(threading.Thread):

# 判断apk应用是否已安装到设备
def is_apk_has_installed(self, package_name, device_id=''):
if device_id != '':
cmd = "adb -s " + device_id + " shell pm list package | grep '" + package_name + "'"
else:
cmd = "adb shell pm list package | grep '" + package_name + "'"
result = os.popen(cmd).read()
if package_name in result:
return True
else:
return False

# 卸载app应用
def uninstall_app(self, package_name, device_id=''):
if device_id != '':
cmd = 'adb -s ' + device_id +' uninstall ' + package_name
else:
cmd = 'adb uninstall ' + package_name
execute.shell(cmd)
print("Uninstall app success~")

# 强制安装
def overlay_install(self, file_path, device_id=''):
if device_id != '':
cmd = 'adb -s ' + device_id + ' install -r ' + file_path
else:
cmd = 'adb install -r ' + file_path
execute.shell(cmd)

# 完全安装,如果已安装应用,需要卸载,重新安装
def completely_install(self, file_path, package_name, device_id=''):
if self.is_apk_has_installed(package_name, device_id):
self.uninstall_app(package_name)
print('Begin to install apk...')
if device_id != '':
cmd = 'adb -s ' + device_id + ' install -r ' + file_path
else:
cmd = 'adb install -r ' + file_path
res = execute.shell(cmd)
if str(res) == 'Success':
print('The apk '+ file_path + ' install successfully')
count = 0
while not self.is_apk_has_installed(package_name) or count > 30:
time.sleep(1)
print('sleep......')
count = count + 1
else:
print('The apk ' + file_path + ' install failed!!!')

4、新建global_parameters.py,用于保存全局变量,代码如下:

class GlobalParameters():

def __init__(self):
global _global_dict
_global_dict = {'_flag': False}

def set_value(self, name, value):
_global_dict[name] = value

def get_value(self, name, defValue=None):
try:
return _global_dict[name]
except KeyError:
return defValue

5、新建app_engine.py,用于安装启动app等,代码如下:

import uiautomator2 as u2
from thread_deal_permission_box import ThreadDealPermissionBox
from adb_completely_install import AdbCompletelyInstall

class AppEngine():

def setUp(self):

self.device = '882QADT9UWT'
self.apk_file = 'xxxxxx.apk'
self.app_package = 'com.xxx'
self.app_activity = 'com.xxx.xxx.HomeActivity'

driver = u2.connect(self.device)

thread_deal_permission_box = ThreadDealPermissionBox(driver)
thread_deal_permission_box.start()
# 完全安装应用
AdbCompletelyInstall().completely_install(self.apk_file, self.app_package, self.device)
driver = self.app_start()
thread_deal_permission_box.terminate() # 停止线程

return driver

# 启动app
def app_start(self):

driver = u2.connect(self.device)
driver.app_start(self.app_package, self.app_activity)

return driver

# 关闭app应用
def app_stop(self):
driver = u2.connect(self.device)
driver.app_stop(self.app_package)

app_engine = AppEngine()
app_engine.setUp()

最后,直接在pycharm中执行app_engine.py文件即可。

共收到 3 条回复 时间 点赞

adb install -g xxx.apk 直接打开全部权限安装

xiaoxiao #2 · June 26, 2019 作者
hljycrgl 回复

之前试过了-g也并不能安装成功,弹窗不点掉的话,最后依然会失败[INSTALL_FAILED_USER_RESTRICTED]我的手机:meizu16😅

你好,我想问下,如果想支持多台手机同时运行,怎么弄哈

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up