ADB命令合集自己记录

安装配置skd

修改安卓模拟器nox_adb.exe文件

ADB命令

基本命令

查看帮助

adb help

查看版本

adb version

查看adb的连接设备:

adb devices

参数 显示列表
无 所有应用
-f 显示应用关联的 apk 文件
-d 只显示 disabled 的应用
-e 只显示 enabled 的应用
-s 只显示系统应用
-3 只显示第三方应用
-i 显示应用的 installer
-u 包含已卸载应用
包名包含 字符串

该命令经常出现以下问题:

  • offline —— 表示设备未连接成功或无响应;
  • device —— 设备已连接;
  • no device —— 没有设备/模拟器连接;
  • List of devices attached 设备/模拟器未连接到 adb 或无响应

链接到夜神模拟器

adb connect 127.0.0.1:62001


#	如果连接不到的时候:先找到端口号
adb nodaemon server
#	在根据 端口号 找到进程的PID
netstat -ano | findstr "5037"
#	在进行清除此PID
taskkill  /pid 22712 -f
#	然后调用 重启 或者手动重新联机即可
adb start-server  
#	或者
adb connect 127.0.0.1:62001

杀进程

 adb kill-server
 
 adb start-server

查看当前的包名类名

adb shell dumpsys activity | find "mFocusedActivity"

打印日志

adb logcat

指定某个应用的日志

adb shell pm list packages tenc //模糊查询带有tenc字符的应用程序

//使用find或者grep来筛选应用日志,这里我拿微信来测试打印日志
adb logcat | grep com.tencent.mm
adb logcat | find "com.tencent.mm"  //find后面需要加上“”引号

日志重定向

adb logcat > 你的文件路径.txt文件
adb logcat > D:\log\032801.txt

从手机拉取信息到本地电脑

adb pull  <手机路径> <本地路径>
#	例如
adb pull /storage/emulated/0/Android/data/com.vphone.launcher/files/download D:\AndroidSdk

从本地拉取到手机中

adb pull <本地路径>  <手机路径> 

登录设备shell 模式

adb shell

解析apk安装包

D:\AndroidSdk\android-sdk-windows\tools 启动cmd并执行下列命令

aapt dump badging  D:\AppTest\weixin.apk

#	并且查找 package 包名
aapt dump badging  C:\Users\askbd\Downloads\jiakaobaodian.apk | findstr package
#	查找对应的包名
aapt dump badging  C:\Users\askbd\Downloads\jiakaobaodian.apk | findstr launchable-activity

查看所有应用

adb shell pm list packages

???

adb nodaemon server

参数 含义
-l 将应用安装到保护目录 /mnt/asec
-r 允许覆盖安装
-t 允许安装 AndroidManifest.xml 里 application 指定 android:testOnly=“true” 的应用
-s 将应用安装到 sdcard
-d 允许降级覆盖安装
-g 授予所有运行时权限

安装app

adb install <安装包路径>

例如:
adb install C:\Users\askbd\Downloads\weixin.apk

查询当前运行app包名

adb shell dumpsys activity | find "mFocusedActivity"

#	检测包的信息
adb shell dumpsys package io.appium.settings

列出所有的包名

adb shell pm list packages

-s列出系统apk路径以及包名
-3列出用户apl路径以及包名

卸载app

adb uninstall <包名>
例如:
adb uninstall com.tencent.mm

启动App

adb shell am start -n 包名/入口
例如:
adb shell am start -n com.tencent.mm/com.tencent.mm.ui.LauncherUI

清除应用的数据和缓存

adb shell pm clear 包名

adb shell pm clear com.tencent.mm

坐标点击

adb shell input tap x轴坐标 y轴坐标

adb shell input tap 600 900

使用 Monkey 进行压力测试

monkey是android自带系统自带的程序,可以生成伪随机用户事件来模拟单击、触摸、手势等操作,可以对正在开发中的程序进行随机压力测试。

简单用法

// 命令,表示向 com.tencent.mm 程序发送 500 个伪随机事件,并且将日志指定位置保存
adb shell monkey -p com.tencent.mm -v 500 > 日志路径.txt
-v 是提升日志级别,最高可加三个-v

//示例输出
  bash arg: -p
  bash arg: com.tencent.mm
  bash arg: -v
  bash arg: 500
args: [-p, com.tencent.mm, -v, 500]
 arg: "-p"
 arg: "com.tencent.mm"
 arg: "-v"
 arg: "500"
data="com.tencent.mm"

Appium原理介绍

{
  "deviceName": "127.0.0.1:62001 device",
  "platformName": "Android",
  "appPackage": "com.tencent.mm",
  "appActivity": "com.tencent.mm.ui.LauncherUI"
}

页面布局

页面控件

ADB组件

API解析

#	currentActivity     可以获取当前前台正在运行的类名
String actual = androidDriver.currentActivity();


#	findElementByAndroidUIAutomator (如果找不到,必须把java版本配置到1.8)
xxxxxxxxx.findElementByAndroidUIAutomator("new UiSelector().text(\"北京\")");

元素定位

id定位

className定位

AccessibilityId定位

xpath定位

1.text常规定位:

比如我要用text属性的文本值定位,这时候只需要写成xpath表达式

xxxxxxxx.findElementByXPath("//android.widget.TextView[@text='北京']").click();

2.contains模糊定位

这种经常用于获取toast的时候,toast文本内容较长,可以采用contains包含部分文本的匹配方式。当然,可以用来模糊匹配上面的文本属性“同意并继续”

# 元素定位
agree_continue_xpath = "//*[@text='同意并继续']"

3.组合定位

比如xpath中同时包含class和text两个属性

# 元素定位
agree_continue_xpath = "//*[@class='android.widget.Button' and @text='同意并继续']"

4.层级定位

使用lazy uiautomatorviewer,可以看到底下有个fullIndexXpath,这种是全路径的形式,也是层级的形式

# 元素定位
agree_continue_xpath = "//android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.RelativeLayout[1]/android.widget.Button[2]"

Android UIAutomator定位

android uiautomator原理是通过android 自带的android uiautomator的类库去查找元素,其实和appium的定位一样,或者说他比appium的定位方式更佳多以及更佳适用,它也支持id、className、text、模糊匹配等进行定位。

1 text定位

ele = self.driver.find_element_by_android_uiautomator('new UiSelector().text("请输入手机号")')
ele.send_keys("123")

1

2 text模糊定位

模糊定位故名思义,通过text的部分信息就能够进行定位,我们直接看代码:

ele = self.driver.find_element_by_android_uiautomator('new UiSelector().textContains("请输入手")')
ele.send_keys("123")

1

3 textStartsWith定位

# 以text什么开始
driver.find_element_by_android_uiautomator('new UiSelector().textStartsWith("请输入")')

1

4 textMatches 正则匹配查找

textMatches故名思义就是通过正则的来进行查找定位,他也是通过text的属性来进行正则匹配,我们直接看代码:

ele = self.driver.find_element_by_android_uiautomator('new UiSelector().textMatches("^请输入手.*")')
ele.send_keys("123")

1

5 resourceID定位

resourceId定位和appium封装好的id定位是一样的,只是这里将写法变成了uiautomator的写法而已,看下面代码

ele = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("cn.com.open.mooc:id/et_phone_edit")')
ele.send_keys('234')

1

6 resourceIDMatches 定位

通过id进行正则匹配定位

ele = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceIdMatches(".+et_phone_edit")')
ele.send_keys('234')

1

7 className定位

通过调用android uiautomator使用className进行定位

ele = self.driver.find_element_by_android_uiautomator('new UiSelector().className("android.widget.EditText")')
ele.send_keys('234')

1

8 classNameMatches定位

通过className正则匹配进行定位

ele = self.driver.find_element_by_android_uiautomator('new UiSelector().classNameMatches (".*EditText")')
ele.send_keys('234')

1

9 组合定位

#组合定位
self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/tab_name").text("我的")').click()

1

# 组合定位,一般组合用id,class,text这三个属性会比较好一点
# id+class 属性组合
id_class = 'resourceId("com.xyh.commerce:id/ll_personal").className("android.widget.LinearLayout")'
driver.find_element_by_android_uiautomator(id_class).click()

10 父子关系、兄弟关系定位

#父子关系定位
self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/title_container").childSelector(text("股票"))')

1

#兄弟关系定位
self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/title_container").fromParent(text("股票"))')

11 滚动查找

#滚动查找
self.driver.find_element_by_android_uiautomator('new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text("查找的元素文本").instance(0));')

1

LazyUiAutomatorViewer

使用lazy uiautomatorviewer,可以看到底下有个uiaSelector,将其拷贝到代码

# 元素定位
agree_continue_android_uiautomator = "new UiSelector().className(\"android.widget.Button\").textContains(\"同意并继续\").resourceId(\"com.baidu.searchbox:id/positive_button\")"
 
WebDriverWait(driver, 10, 1).until(EC.visibility_of_element_located((MobileBy.ANDROID_UIAUTOMATOR, agree_continue_android_uiautomator)))
driver.find_element_by_android_uiautomator(agree_continue_android_uiautomator).click()

appium与selenium元素定位之比较


框架 常用的元素定位方式 备注
appium id, className, AccessibilityId, xpath, AndroidUIAutomator 对于h5页面,也支持selenium的name, link text, css等定位方式
selenium id, className, name, tag name, link text, paratial link text, xpath ,css

元素等待类型

强制等待

  • 固定的等待时间:
    • Thread.sleep()

隐式等待

  • 针对全局元素设置等待时间
    • androidDriver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
      

显式等待

  • 针对某个元素设置等待时间
    • WebDriverWait
      

手势操作

滑动

  • java-client 5.0之前版本有提供滑动的API ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  • startx,starty 	#	起始点坐标的x , y轴值
    endx , endy 	#	终止点坐标的x, y轴值
    duration		#	从起始点到终止点的滑动时间
    androidDriver.swipe(startx,starty,endx,endy,duration);
    

Maven项目配置

Java Client包地址

eclipse中安装TestNG

方法1:直接Help-> Eclipse Marketplace 下面搜索testng,出来后直接点Install

方法2:使用archive方式安装
先下载eclipse-testng: http://dl.bintray.com/testng-team/testng-eclipse-release/

使用java代码启动app程序

前提:

  1. 提前在模拟器中安装好app应用

  2. 连接好模拟器 adb connect 127.0.0.1:62001

  3. 打开好Appium 并运行

    package com.test.firstAppium;

    import java.net.MalformedURLException;
    import java.net.URL;

    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.remote.DesiredCapabilities;

    import io.appium.java_client.android.AndroidDriver;

    public class AppiumTest {
    //此方法为启动App应用程序
    public static void main(String[] args) throws MalformedURLException {
    //1创建配置对象
    DesiredCapabilities desiredCapabilities =new DesiredCapabilities();
    //2.添加配置
    //deviceName: 可以找到我们测试的设备
    desiredCapabilities.setCapability(“deviceName”,“127.0.0.1:62001”);
    //paltformName:测试平台Android or ios
    desiredCapabilities.setCapability(“platformName”,“Android”);
    //appPackage : 找到想要的测试App
    desiredCapabilities.setCapability(“appPackage”,“com.handsgo.jiakao.android”);
    //appActivity : 测试app入口
    desiredCapabilities.setCapability(“appActivity”,“com.handsgo.jiakao.android.splash.Login”);

     	//3创建驱动
     	//传入连个参数
     	//第一个参数:Appium通讯地址		
     	//第二个参数:配置对象
     	AndroidDriver<WebElement> androidDriver =new AndroidDriver<WebElement>(
     			new URL("http://127.0.0.1:4723/wd/hub"),desiredCapabilities);
     }
    

    }

使用java脚本启动驾考宝典app

package com.test.firstAppium;

import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Driver;

import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.android.AndroidDriver;

public class  AppiumTest   {
	
	public static  AndroidDriver<WebElement>androidDriver;
	//此方法为启动App应用程序
	public static void main(String[] args) throws MalformedURLException, InterruptedException {
		//1创建配置对象
		DesiredCapabilities desiredCapabilities =new DesiredCapabilities();
		//2.添加配置
		//deviceName: 可以找到我们测试的设备
		desiredCapabilities.setCapability("deviceName","127.0.0.1:62001");
		//paltformName:测试平台Android or ios
		desiredCapabilities.setCapability("platformName","Android");
		//appPackage : 找到想要的测试App
		desiredCapabilities.setCapability("appPackage","com.handsgo.jiakao.android");
		
		//automationName:uiautomator2来解决输入框输入不了数据
		//自动化引擎
		desiredCapabilities.setCapability("unicodeKeyboard", "true");
		desiredCapabilities.setCapability("resetKeyboard", "true");
//		desiredCapabilities.setCapability("automationName","uiautomator2");


		//appActivity : 测试app入口
		desiredCapabilities.setCapability("appActivity","com.handsgo.jiakao.android.splash.Login");
		
		//3创建驱动
		//传入连个参数
		//第一个参数:Appium通讯地址		
		//第二个参数:配置对象
		androidDriver =new AndroidDriver<WebElement>(
				new URL("http://127.0.0.1:4723/wd/hub"),desiredCapabilities);
		
		//调用驾考这个方法
		testJiaKao();
		
	}
	public static void testJiaKao() throws InterruptedException {
		//等待元素加载完毕
		Thread.sleep(5000);
		
		//点击同意并继续
		androidDriver.findElementById("com.handsgo.jiakao.android:id/btn_agree").click();
		Thread.sleep(10000);
		
		//点击夏考宝典申请获得以下权限 的知道了
		androidDriver.findElementById("com.handsgo.jiakao.android:id/permission_box").click();
		androidDriver.findElementById("com.handsgo.jiakao.android:id/permission_btn").click();
		Thread.sleep(2000);
		
		
		//1.找到定位城市文本,并且点击
		androidDriver.findElementById("com.handsgo.jiakao.android:id/cityTv").click();
		Thread.sleep(5000);
		//2.找到城市搜索框并且输入"北京"
		androidDriver.findElementById("com.handsgo.jiakao.android:id/edt_search_q").sendKeys("北京");
		//3 选择北京
		androidDriver.findElementById("com.handsgo.jiakao.android:id/item_title").click();
		//4找到小车并点击
		androidDriver.findElementById("com.handsgo.jiakao.android:id/itemCar").click();
		Thread.sleep(4000);
		
		//5点击报名状态为 已报名驾校
		androidDriver.findElementById("com.handsgo.jiakao.android:id/registeredTv").click();
		
		//点击性别为男
		androidDriver.findElementById("com.handsgo.jiakao.android:id/maleTv").click();
		
		//6.找到下一步,并且点击
		androidDriver.findElementById("com.handsgo.jiakao.android:id/okBtn").click();
		Thread.sleep(2000);
		
		//1选择暂不绑定
		androidDriver.findElementById("com.handsgo.jiakao.android:id/tv_un_bind").click();
		
	}
}

下拉刷新

package com.test.firstAppium;

import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import org.testng.reporters.jq.Main;

import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Driver;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.WebDriverWait;

import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.functions.ExpectedCondition;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;

public class AppiumTestShuaXin {

	public static AndroidDriver<WebElement> androidDriver;

	@BeforeTest
	public void setUp() throws MalformedURLException, InterruptedException {
		// 1创建配置对象
		DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
		// 2.添加配置
		// deviceName: 可以找到我们测试的设备
		desiredCapabilities.setCapability("deviceName", "127.0.0.1:62001");
		// paltformName:测试平台Android or ios
		desiredCapabilities.setCapability("platformName", "Android");
		// appPackage : 找到想要的测试App
		desiredCapabilities.setCapability("appPackage", "com.handsgo.jiakao.android");

		// noReset: 不清除应用的数据启动测试 ture表示不清除; 默认false表示清除
		desiredCapabilities.setCapability("noReset", "true");

		// automationName:uiautomator2来解决输入框输入不了数据
		// 自动化引擎
//		desiredCapabilities.setCapability("unicodeKeyboard", "true");
//		desiredCapabilities.setCapability("resetKeyboard", "true");
		desiredCapabilities.setCapability("automationName", "uiautomator2");

		// appActivity : 测试app入口
		desiredCapabilities.setCapability("appActivity", "com.handsgo.jiakao.android.splash.Login");
		Thread.sleep(10000);

		// 3创建驱动
		// 传入连个参数
		// 第一个参数:Appium通讯地址
		// 第二个参数:配置对象
		androidDriver = new AndroidDriver<WebElement>(new URL("http://127.0.0.1:4723/wd/hub"), desiredCapabilities);

		// 设置隐式等待
//		androidDriver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

	}

//	@Test(enabled = false)
	@Test
	public void testJiaKao() throws InterruptedException {

		Thread.sleep(10000);

		// 下拉刷新 7.3.0
		TouchAction<?> touchAction = new TouchAction<>(androidDriver);
		//
		// 把原始的坐标转化成pointOption类型的
		PointOption startPointOption = PointOption.point(356, 594);
		PointOption endPointOption = PointOption.point(356, 794);
		// 把原始的时间装换成Duration类型
		Duration duration = Duration.ofMillis(800);
		// 在转化成WaitOptions类型的
		WaitOptions waitOptions = WaitOptions.waitOptions(duration);

		touchAction.press(startPointOption).waitAction(waitOptions).moveTo(endPointOption).release();
		// 让我们的滑动生效
		touchAction.perform();

	}

	@AfterTest
	public void tearDown() {
		// 当测试用例测试完毕,我们销毁驱动
		androidDriver.quit();

	}
}

错误合集

夜神模拟器 冲突问题

把D:\AndroidSdk\android-sdk-windows\platform-tools\adb.exe 文件

修改名称为 =nox_adb=

D:\安卓模拟器\Nox\bin\nox_adb.exe

uiautomatorviewer 定位提示Error obtaining UI hierarchy

这是因为工具不太稳定导致的

  1. 首先检查你的jdk版本是不是1.8或1.8以下,因为1.9的jdk不兼容uiautomatorviewer
  2. 进入任务管理器,停止adb.exe,然后在CMD界面输入adb connect xxx,再输入adb devices后,再点击uiautomatorview.bat文件去运行
  3. 再多试几次还是不行的话,建议使用appium自带的元素定位去定位,毕竟这个uiautomatorviewer不稳定

或者 杀进程:

1.sudo adb kill-server

2.sudo adb start-server

Unable to start adb server: error: protocol fault (couldn’t read status): Connection reset by peer

大多数情况是5037端口被占用。5037为adb默认端口。
解决办法:

  1. 查看哪个程序占用了adb端口,结束这个程序,然后重启adb就好了。

  2. 使用命令:=netstat -aon|findstr “5037”= 找到占用5037端口的进程PID。

  3. 使用命令:=tasklist|findstr “5440”= 通过PID找出进程。

  4. 调出任务管理器,找到这个进程,结束进程。
    使用命令:adb start-server 启动adb就行了


版权声明:本文为qq_43073903原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。