ADB命令合集自己记录
安裝配置skd
修改安卓模擬器nox_adb.exe文件
ADB命令
基本命令
查看幫助
adb help查看版本
adb version查看adb的連接設(shè)備:
adb devices參數(shù) 顯示列表
無(wú) 所有應(yīng)用
-f 顯示應(yīng)用關(guān)聯(lián)的 apk 文件
-d 只顯示 disabled 的應(yīng)用
-e 只顯示 enabled 的應(yīng)用
-s 只顯示系統(tǒng)應(yīng)用
-3 只顯示第三方應(yīng)用
-i 顯示應(yīng)用的 installer
-u 包含已卸載應(yīng)用
包名包含 字符串
該命令經(jīng)常出現(xiàn)以下問題:
- offline —— 表示設(shè)備未連接成功或無(wú)響應(yīng);
- device —— 設(shè)備已連接;
- no device —— 沒有設(shè)備/模擬器連接;
- List of devices attached 設(shè)備/模擬器未連接到 adb 或無(wú)響應(yīng)
鏈接到夜神模擬器
adb connect 127.0.0.1:62001# 如果連接不到的時(shí)候:先找到端口號(hào) adb nodaemon server # 在根據(jù) 端口號(hào) 找到進(jìn)程的PID netstat -ano | findstr "5037" # 在進(jìn)行清除此PID taskkill /pid 22712 -f # 然后調(diào)用 重啟 或者手動(dòng)重新聯(lián)機(jī)即可 adb start-server # 或者 adb connect 127.0.0.1:62001殺進(jìn)程
adb kill-serveradb start-server查看當(dāng)前的包名類名
adb shell dumpsys activity | find "mFocusedActivity"打印日志
adb logcat指定某個(gè)應(yīng)用的日志
adb shell pm list packages tenc //模糊查詢帶有tenc字符的應(yīng)用程序//使用find或者grep來(lái)篩選應(yīng)用日志,這里我拿微信來(lái)測(cè)試打印日志 adb logcat | grep com.tencent.mm adb logcat | find "com.tencent.mm" //find后面需要加上“”引號(hào)日志重定向
adb logcat > 你的文件路徑.txt文件 adb logcat > D:\log\032801.txt從手機(jī)拉取信息到本地電腦
adb pull <手機(jī)路徑> <本地路徑> # 例如 adb pull /storage/emulated/0/Android/data/com.vphone.launcher/files/download D:\AndroidSdk從本地拉取到手機(jī)中
adb pull <本地路徑> <手機(jī)路徑>登錄設(shè)備shell 模式
adb shell解析apk安裝包
D:\AndroidSdk\android-sdk-windows\tools 啟動(dòng)cmd并執(zhí)行下列命令
aapt dump badging D:\AppTest\weixin.apk# 并且查找 package 包名 aapt dump badging C:\Users\askbd\Downloads\jiakaobaodian.apk | findstr package # 查找對(duì)應(yīng)的包名 aapt dump badging C:\Users\askbd\Downloads\jiakaobaodian.apk | findstr launchable-activity查看所有應(yīng)用
adb shell pm list packages???
adb nodaemon server參數(shù) 含義
-l 將應(yīng)用安裝到保護(hù)目錄 /mnt/asec
-r 允許覆蓋安裝
-t 允許安裝 AndroidManifest.xml 里 application 指定 android:testOnly=“true” 的應(yīng)用
-s 將應(yīng)用安裝到 sdcard
-d 允許降級(jí)覆蓋安裝
-g 授予所有運(yùn)行時(shí)權(quán)限
安裝app
adb install <安裝包路徑>例如: adb install C:\Users\askbd\Downloads\weixin.apk查詢當(dāng)前運(yùn)行app包名
adb shell dumpsys activity | find "mFocusedActivity"# 檢測(cè)包的信息 adb shell dumpsys package io.appium.settings列出所有的包名
adb shell pm list packages-s列出系統(tǒng)apk路徑以及包名 -3列出用戶apl路徑以及包名卸載app
adb uninstall <包名> 例如: adb uninstall com.tencent.mm啟動(dòng)App
adb shell am start -n 包名/入口 例如: adb shell am start -n com.tencent.mm/com.tencent.mm.ui.LauncherUI清除應(yīng)用的數(shù)據(jù)和緩存
adb shell pm clear 包名adb shell pm clear com.tencent.mm坐標(biāo)點(diǎn)擊
adb shell input tap x軸坐標(biāo) y軸坐標(biāo)adb shell input tap 600 900使用 Monkey 進(jìn)行壓力測(cè)試
monkey是android自帶系統(tǒng)自帶的程序,可以生成偽隨機(jī)用戶事件來(lái)模擬單擊、觸摸、手勢(shì)等操作,可以對(duì)正在開發(fā)中的程序進(jìn)行隨機(jī)壓力測(cè)試。
簡(jiǎn)單用法
// 命令,表示向 com.tencent.mm 程序發(fā)送 500 個(gè)偽隨機(jī)事件,并且將日志指定位置保存 adb shell monkey -p com.tencent.mm -v 500 > 日志路徑.txt -v 是提升日志級(jí)別,最高可加三個(gè)-v//示例輸出bash arg: -pbash arg: com.tencent.mmbash arg: -vbash 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" }頁(yè)面布局
頁(yè)面控件
ADB組件
API解析
# currentActivity 可以獲取當(dāng)前前臺(tái)正在運(yùn)行的類名 String actual = androidDriver.currentActivity();# findElementByAndroidUIAutomator (如果找不到,必須把java版本配置到1.8) xxxxxxxxx.findElementByAndroidUIAutomator("new UiSelector().text(\"北京\")");元素定位
id定位
className定位
AccessibilityId定位
xpath定位
1.text常規(guī)定位:
比如我要用text屬性的文本值定位,這時(shí)候只需要寫成xpath表達(dá)式
xxxxxxxx.findElementByXPath("//android.widget.TextView[@text='北京']").click();2.contains模糊定位
這種經(jīng)常用于獲取toast的時(shí)候,toast文本內(nèi)容較長(zhǎng),可以采用contains包含部分文本的匹配方式。當(dāng)然,可以用來(lái)模糊匹配上面的文本屬性“同意并繼續(xù)”
# 元素定位 agree_continue_xpath = "//*[@text='同意并繼續(xù)']"3.組合定位
比如xpath中同時(shí)包含class和text兩個(gè)屬性
# 元素定位 agree_continue_xpath = "//*[@class='android.widget.Button' and @text='同意并繼續(xù)']"4.層級(jí)定位
使用lazy uiautomatorviewer,可以看到底下有個(gè)fullIndexXpath,這種是全路徑的形式,也是層級(jí)的形式
# 元素定位 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原理是通過(guò)android 自帶的android uiautomator的類庫(kù)去查找元素,其實(shí)和appium的定位一樣,或者說(shuō)他比appium的定位方式更佳多以及更佳適用,它也支持id、className、text、模糊匹配等進(jìn)行定位。
1 text定位
ele = self.driver.find_element_by_android_uiautomator('new UiSelector().text("請(qǐng)輸入手機(jī)號(hào)")') ele.send_keys("123")1
2 text模糊定位
模糊定位故名思義,通過(guò)text的部分信息就能夠進(jìn)行定位,我們直接看代碼:
ele = self.driver.find_element_by_android_uiautomator('new UiSelector().textContains("請(qǐng)輸入手")') ele.send_keys("123")1
3 textStartsWith定位
# 以text什么開始 driver.find_element_by_android_uiautomator('new UiSelector().textStartsWith("請(qǐng)輸入")')1
4 textMatches 正則匹配查找
textMatches故名思義就是通過(guò)正則的來(lái)進(jìn)行查找定位,他也是通過(guò)text的屬性來(lái)進(jìn)行正則匹配,我們直接看代碼:
ele = self.driver.find_element_by_android_uiautomator('new UiSelector().textMatches("^請(qǐng)輸入手.*")') 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 定位
通過(guò)id進(jìn)行正則匹配定位
ele = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceIdMatches(".+et_phone_edit")') ele.send_keys('234')1
7 className定位
通過(guò)調(diào)用android uiautomator使用className進(jìn)行定位
ele = self.driver.find_element_by_android_uiautomator('new UiSelector().className("android.widget.EditText")') ele.send_keys('234')1
8 classNameMatches定位
通過(guò)className正則匹配進(jìn)行定位
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這三個(gè)屬性會(huì)比較好一點(diǎn) # 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 父子關(guān)系、兄弟關(guān)系定位
#父子關(guān)系定位 self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/title_container").childSelector(text("股票"))')1
#兄弟關(guān)系定位 self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/title_container").fromParent(text("股票"))')11 滾動(dòng)查找
#滾動(dòng)查找 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,可以看到底下有個(gè)uiaSelector,將其拷貝到代碼
# 元素定位 agree_continue_android_uiautomator = "new UiSelector().className(\"android.widget.Button\").textContains(\"同意并繼續(xù)\").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 對(duì)于h5頁(yè)面,也支持selenium的name, link text, css等定位方式
selenium id, className, name, tag name, link text, paratial link text, xpath ,css
元素等待類型
強(qiáng)制等待
- 固定的等待時(shí)間:
- Thread.sleep()
隱式等待
- 針對(duì)全局元素設(shè)置等待時(shí)間
- androidDriver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
顯式等待
- 針對(duì)某個(gè)元素設(shè)置等待時(shí)間
- WebDriverWait
手勢(shì)操作
滑動(dòng)
- java-client 5.0之前版本有提供滑動(dòng)的API ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
- startx,starty # 起始點(diǎn)坐標(biāo)的x , y軸值 endx , endy # 終止點(diǎn)坐標(biāo)的x, y軸值 duration # 從起始點(diǎn)到終止點(diǎn)的滑動(dòng)時(shí)間 androidDriver.swipe(startx,starty,endx,endy,duration);
Maven項(xiàng)目配置
Java Client包地址
eclipse中安裝TestNG
方法1:直接Help-> Eclipse Marketplace 下面搜索testng,出來(lái)后直接點(diǎn)Install
方法2:使用archive方式安裝
先下載eclipse-testng: http://dl.bintray.com/testng-team/testng-eclipse-release/
使用java代碼啟動(dòng)app程序
前提:
提前在模擬器中安裝好app應(yīng)用
連接好模擬器 adb connect 127.0.0.1:62001
打開好Appium 并運(yùn)行
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 {
//此方法為啟動(dòng)App應(yīng)用程序
public static void main(String[] args) throws MalformedURLException {
//1創(chuàng)建配置對(duì)象
DesiredCapabilities desiredCapabilities =new DesiredCapabilities();
//2.添加配置
//deviceName: 可以找到我們測(cè)試的設(shè)備
desiredCapabilities.setCapability(“deviceName”,“127.0.0.1:62001”);
//paltformName:測(cè)試平臺(tái)Android or ios
desiredCapabilities.setCapability(“platformName”,“Android”);
//appPackage : 找到想要的測(cè)試App
desiredCapabilities.setCapability(“appPackage”,“com.handsgo.jiakao.android”);
//appActivity : 測(cè)試app入口
desiredCapabilities.setCapability(“appActivity”,“com.handsgo.jiakao.android.splash.Login”);
}
使用java腳本啟動(dòng)駕考寶典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;//此方法為啟動(dòng)App應(yīng)用程序public static void main(String[] args) throws MalformedURLException, InterruptedException {//1創(chuàng)建配置對(duì)象DesiredCapabilities desiredCapabilities =new DesiredCapabilities();//2.添加配置//deviceName: 可以找到我們測(cè)試的設(shè)備desiredCapabilities.setCapability("deviceName","127.0.0.1:62001");//paltformName:測(cè)試平臺(tái)Android or iosdesiredCapabilities.setCapability("platformName","Android");//appPackage : 找到想要的測(cè)試AppdesiredCapabilities.setCapability("appPackage","com.handsgo.jiakao.android");//automationName:uiautomator2來(lái)解決輸入框輸入不了數(shù)據(jù)//自動(dòng)化引擎desiredCapabilities.setCapability("unicodeKeyboard", "true");desiredCapabilities.setCapability("resetKeyboard", "true"); // desiredCapabilities.setCapability("automationName","uiautomator2");//appActivity : 測(cè)試app入口desiredCapabilities.setCapability("appActivity","com.handsgo.jiakao.android.splash.Login");//3創(chuàng)建驅(qū)動(dòng)//傳入連個(gè)參數(shù)//第一個(gè)參數(shù):Appium通訊地址 //第二個(gè)參數(shù):配置對(duì)象androidDriver =new AndroidDriver<WebElement>(new URL("http://127.0.0.1:4723/wd/hub"),desiredCapabilities);//調(diào)用駕考這個(gè)方法testJiaKao();}public static void testJiaKao() throws InterruptedException {//等待元素加載完畢Thread.sleep(5000);//點(diǎn)擊同意并繼續(xù)androidDriver.findElementById("com.handsgo.jiakao.android:id/btn_agree").click();Thread.sleep(10000);//點(diǎn)擊夏考寶典申請(qǐng)獲得以下權(quán)限 的知道了androidDriver.findElementById("com.handsgo.jiakao.android:id/permission_box").click();androidDriver.findElementById("com.handsgo.jiakao.android:id/permission_btn").click();Thread.sleep(2000);//1.找到定位城市文本,并且點(diǎn)擊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找到小車并點(diǎn)擊androidDriver.findElementById("com.handsgo.jiakao.android:id/itemCar").click();Thread.sleep(4000);//5點(diǎn)擊報(bào)名狀態(tài)為 已報(bào)名駕校androidDriver.findElementById("com.handsgo.jiakao.android:id/registeredTv").click();//點(diǎn)擊性別為男androidDriver.findElementById("com.handsgo.jiakao.android:id/maleTv").click();//6.找到下一步,并且點(diǎn)擊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;@BeforeTestpublic void setUp() throws MalformedURLException, InterruptedException {// 1創(chuàng)建配置對(duì)象DesiredCapabilities desiredCapabilities = new DesiredCapabilities();// 2.添加配置// deviceName: 可以找到我們測(cè)試的設(shè)備desiredCapabilities.setCapability("deviceName", "127.0.0.1:62001");// paltformName:測(cè)試平臺(tái)Android or iosdesiredCapabilities.setCapability("platformName", "Android");// appPackage : 找到想要的測(cè)試AppdesiredCapabilities.setCapability("appPackage", "com.handsgo.jiakao.android");// noReset: 不清除應(yīng)用的數(shù)據(jù)啟動(dòng)測(cè)試 ture表示不清除; 默認(rèn)false表示清除desiredCapabilities.setCapability("noReset", "true");// automationName:uiautomator2來(lái)解決輸入框輸入不了數(shù)據(jù)// 自動(dòng)化引擎 // desiredCapabilities.setCapability("unicodeKeyboard", "true"); // desiredCapabilities.setCapability("resetKeyboard", "true");desiredCapabilities.setCapability("automationName", "uiautomator2");// appActivity : 測(cè)試app入口desiredCapabilities.setCapability("appActivity", "com.handsgo.jiakao.android.splash.Login");Thread.sleep(10000);// 3創(chuàng)建驅(qū)動(dòng)// 傳入連個(gè)參數(shù)// 第一個(gè)參數(shù):Appium通訊地址// 第二個(gè)參數(shù):配置對(duì)象androidDriver = new AndroidDriver<WebElement>(new URL("http://127.0.0.1:4723/wd/hub"), desiredCapabilities);// 設(shè)置隱式等待 // androidDriver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);}// @Test(enabled = false)@Testpublic void testJiaKao() throws InterruptedException {Thread.sleep(10000);// 下拉刷新 7.3.0TouchAction<?> touchAction = new TouchAction<>(androidDriver);//// 把原始的坐標(biāo)轉(zhuǎn)化成pointOption類型的PointOption startPointOption = PointOption.point(356, 594);PointOption endPointOption = PointOption.point(356, 794);// 把原始的時(shí)間裝換成Duration類型Duration duration = Duration.ofMillis(800);// 在轉(zhuǎn)化成WaitOptions類型的WaitOptions waitOptions = WaitOptions.waitOptions(duration);touchAction.press(startPointOption).waitAction(waitOptions).moveTo(endPointOption).release();// 讓我們的滑動(dòng)生效touchAction.perform();}@AfterTestpublic void tearDown() {// 當(dāng)測(cè)試用例測(cè)試完畢,我們銷毀驅(qū)動(dòng)androidDriver.quit();} }錯(cuò)誤合集
夜神模擬器 沖突問題
把D:\AndroidSdk\android-sdk-windows\platform-tools\adb.exe 文件
修改名稱為 =nox_adb=
D:\安卓模擬器\Nox\bin\nox_adb.exe
uiautomatorviewer 定位提示Error obtaining UI hierarchy
這是因?yàn)楣ぞ卟惶€(wěn)定導(dǎo)致的
或者 殺進(jìn)程:
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
大多數(shù)情況是5037端口被占用。5037為adb默認(rèn)端口。
解決辦法:
查看哪個(gè)程序占用了adb端口,結(jié)束這個(gè)程序,然后重啟adb就好了。
使用命令:=netstat -aon|findstr “5037”= 找到占用5037端口的進(jìn)程PID。
使用命令:=tasklist|findstr “5440”= 通過(guò)PID找出進(jìn)程。
調(diào)出任務(wù)管理器,找到這個(gè)進(jìn)程,結(jié)束進(jìn)程。
使用命令:adb start-server 啟動(dòng)adb就行了
總結(jié)
以上是生活随笔為你收集整理的ADB命令合集自己记录的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux .so文件
- 下一篇: 期刊/会议模板