? ? ? 昨晚正在測(cè)case的時(shí)候,突然冒出來(lái)一同事(我們都叫他肖總),來(lái)了一句:BUG基(同事都叫我BUG基,你懂的),我這復(fù)現(xiàn)了一個(gè)問(wèn)題,但是開發(fā)那邊說(shuō)叫我把log導(dǎo)出來(lái),我這不會(huì)導(dǎo),你知道怎么導(dǎo)嗎?
? ? ? 作為一只BUG基,我怎么可能會(huì)放過(guò)這個(gè)裝比的機(jī)會(huì)呢,哈哈。
? ? ? 叫肖總導(dǎo)log的那個(gè)開發(fā)啥也沒(méi)說(shuō),就只在jira系統(tǒng)的comments最后寫了一句“導(dǎo)出方法:adb pull/cache/recovery/ ./”。其實(shí)當(dāng)時(shí)我是崩潰的,我擦,肖總,你妹,這開發(fā)不是說(shuō)了導(dǎo)出方法了嗎?你直接復(fù)制粘貼打上去命令不就行了嗎?然而,裝比心理作怪,我還是決定了幫他。
那么下一步是什么?沒(méi)錯(cuò),是時(shí)候展現(xiàn)裝比的技術(shù)了!
? ? ? ?拿過(guò)Pad的第一步,那當(dāng)然是先裝驅(qū)動(dòng)啦。沒(méi)驅(qū)動(dòng)你怎么使用adb命令?為什么這么說(shuō)呢。驅(qū)動(dòng)一般指的是設(shè)備驅(qū)動(dòng)程序(Device Driver),是一種可以使計(jì)算機(jī)和設(shè)備通信的特殊程序。相當(dāng)于硬件的接口,操作系統(tǒng)只有通過(guò)這個(gè)接口,才能控制硬件設(shè)備的工作,假如某設(shè)備的驅(qū)動(dòng)程序未能正確安裝,便不能正常工作。那么ADB又是什么東東?Android Debug Bridge,我們一般簡(jiǎn)稱為adb,它是一個(gè)非常強(qiáng)大的命令行工具,通過(guò)這個(gè)工具你能夠與你的android設(shè)備進(jìn)行交互。意思也就是說(shuō),ADB命令需要通過(guò)驅(qū)動(dòng)程序提供的接口來(lái)控制硬件設(shè)備,因?yàn)槲覀兊奈募谴鎯?chǔ)在硬件設(shè)備上的呀。
? ? ? ?那裝驅(qū)動(dòng)要在什么狀態(tài)下安裝?廢話,肯定是開機(jī)狀態(tài)啦。當(dāng)然在安裝驅(qū)動(dòng)前,要先開啟開發(fā)者模式的ADB調(diào)試,這里我就不說(shuō)為什么了,自己想。
? ? ? ?那再下一步就是我們要用開發(fā)給的adb命令,導(dǎo)出/cache/recovery/這個(gè)文件夾的內(nèi)容?;蛟S有人會(huì)問(wèn),這開發(fā)不是已經(jīng)給了文件的路勁了嗎,直接在Pad上復(fù)制粘貼到SD卡又或者直接用PC從Pad復(fù)制粘貼到PC就可以了呀。對(duì)于這個(gè),我只想說(shuō),廢話,這么簡(jiǎn)單的,你會(huì)想不到嗎?你以為我是豬啊。然而我并不是豬,我是BUG基。
? ? ? ?對(duì)于上面那個(gè)想法,條件并不成立,當(dāng)我們連接Pad時(shí),windows是屏蔽部分文件的,反正我這里是這個(gè)情況,而用Pad直接復(fù)制粘貼到SD卡也是不成立,當(dāng)我復(fù)制的時(shí)候,會(huì)提示“操作失敗,目標(biāo)無(wú)法復(fù)制”,至于為什么會(huì)出現(xiàn)這個(gè)提示,請(qǐng)往下看。
? ? ? ?既然上面兩個(gè)方法都不行,那我們就只有用adb命令了。
? ? ? ?在執(zhí)行操作之前,我們要先看移動(dòng)設(shè)備是否跟PC連接,那么就需要用adb devices這個(gè)命令查看當(dāng)前連接的設(shè)備,這里可能返回的狀態(tài)有三種:
I.device設(shè)備已經(jīng)成功連接到了adb-server
II.offline設(shè)備并沒(méi)有連接到adb或者沒(méi)有響應(yīng)
III.no device并沒(méi)有設(shè)備/模擬器連接
? ? ? 這里說(shuō)的三種狀態(tài)顯示的可能跟顯示情況不大一樣,譬如我連接是正常的,返回的是
? ? ? 或許有人知道這里的意思是什么,但是是否有想到過(guò)前面的那個(gè)daemon是什么呢?當(dāng)然有人會(huì)說(shuō),只要復(fù)制粘貼會(huì)用就可以了,對(duì)于這個(gè)回答,我默默表示不回答。
? ? ? 這個(gè)daemon還得要從ADB說(shuō)起,ADB包含了以下三部分的cs模式的程序:
? ? ?而在解釋上圖的意思之前,我想先引入兩個(gè)概念,那就是端口和通信(已理解的可以略過(guò))。
端口
? ? ? ?計(jì)算機(jī)"端口"是英文port的譯義,可以認(rèn)為是計(jì)算機(jī)與外界通訊交流的出口。其中硬件領(lǐng)域的端口又稱接口,如:USB端口、串行端口等。軟件領(lǐng)域的端口一般指網(wǎng)絡(luò)中面向連接服務(wù)和無(wú)連接服務(wù)的通信協(xié)議端口,是一種抽象的軟件結(jié)構(gòu),包括一些數(shù)據(jù)結(jié)構(gòu)和I/O(基本輸入輸出)緩沖區(qū)。
? ? ? ? 端口最主要的作用就是通信和數(shù)據(jù)傳輸,把數(shù)據(jù)報(bào)順利的傳送到目的主機(jī)是沒(méi)有問(wèn)題的。那么問(wèn)題出在哪里呢?我們知道大多數(shù)操作系統(tǒng)都支持多程序(進(jìn)程)同時(shí)運(yùn)行,那么目的主機(jī)應(yīng)該把接收到的數(shù)據(jù)報(bào)傳送給眾多同時(shí)運(yùn)行的進(jìn)程中的哪一個(gè)呢?顯然這個(gè)問(wèn)題有待解決,端口機(jī)制便由此被引入進(jìn)來(lái)。
? ? ? ? 本地操作系統(tǒng)會(huì)給那些有需求的進(jìn)程分配協(xié)議端口(protocal port,即我們常說(shuō)的端口),每個(gè)協(xié)議端口由一個(gè)正整數(shù)標(biāo)識(shí),如:80,139,445,等等。當(dāng)目的主機(jī)接收到數(shù)據(jù)報(bào)后,將根據(jù)報(bào)文首部的目的端口號(hào),把數(shù)據(jù)發(fā)送到相應(yīng)端口,而與此端口相對(duì)應(yīng)的那個(gè)進(jìn)程將會(huì)領(lǐng)取數(shù)據(jù)并等待下一組數(shù)據(jù)的到來(lái)。說(shuō)到這里,端口的概念似乎仍然抽象,那么繼續(xù)跟我來(lái),別走開。
? ? ? ? ?端口其實(shí)就是隊(duì),操作系統(tǒng)為各個(gè)進(jìn)程分配了不同的隊(duì),數(shù)據(jù)報(bào)按照目的端口被推入相應(yīng)的隊(duì)中,等待被進(jìn)程取用,在極特殊的情況下,這個(gè)隊(duì)也是有可能溢出的,不過(guò)操作系統(tǒng)允許各進(jìn)程指定和調(diào)整自己的隊(duì)的大小。
通信
? ? ? ? 通信(Communication)就是信息的傳遞,是指由一地向另一地進(jìn)行信息的傳輸與交換,其目的是傳輸消息。其實(shí)這里的通信,意思就是說(shuō)用特定的邏輯信號(hào),實(shí)現(xiàn)雙方的互相信息傳輸,譬如說(shuō)在命令行輸入adb devices命令,意思就是說(shuō)我想要對(duì)方輸出設(shè)備列表給我看,這里的輸入”adb devices”就是發(fā)送給對(duì)方的信號(hào),而輸出的設(shè)備列表就是對(duì)方反饋回來(lái)的信號(hào),這個(gè)整個(gè)過(guò)程就是通信的過(guò)程。
? ? ? 說(shuō)了這么多,其目的就在于掃盲,下面我們來(lái)說(shuō)上面提到的ADB三部分的cs模式的程序(我把上面的圖拉下來(lái),防止大家看不到):
1) adb client
? ? ? 從圖中,我們知道client是運(yùn)行在PC端的,每當(dāng)我們發(fā)起一個(gè)adb命令的時(shí)候,就會(huì)開啟一個(gè)client程序。當(dāng)然,當(dāng)我們開啟DDMS或者ADT的時(shí)候,也會(huì)自動(dòng)創(chuàng)建client。
? ? ? 當(dāng)我們開啟一個(gè)client的時(shí)候,它首先會(huì)去檢測(cè)后臺(tái)是否已經(jīng)有一個(gè)server程序在運(yùn)行著,否則會(huì)開啟一個(gè)adb-server進(jìn)程。
? ? ? ?所有的client都是通過(guò)5037端口與adb-server進(jìn)行通信的。
2)adb daemon(adbd)
? ? ? ?從圖中,我們知道daemon是作為一個(gè)后臺(tái)進(jìn)程運(yùn)行在模擬器/真實(shí)Android設(shè)備中的。
? ? ? ?daemon使用端口的范圍是5554-5585,每個(gè)模擬器/設(shè)備連接到PC端時(shí),總會(huì)開啟這么一個(gè)后臺(tái)進(jìn)程,并且為其分配了兩個(gè)連續(xù)的端口,比如:
? ? ? Emulator 1,console: 5554
? ? ? Emulator 1, adb:5555
? ? ? 也正因?yàn)槊總€(gè)設(shè)備都分一組兩個(gè)端口,也已a(bǔ)db連接手機(jī)的最大數(shù)量為16。
? ? ? 說(shuō)回端口的作用,在這兩個(gè)端口中,其中偶數(shù)端口是用于server與設(shè)備進(jìn)行交互的,可以讓server直接從設(shè)備中讀取數(shù)據(jù),而奇數(shù)端口是用來(lái)與設(shè)備的adbd進(jìn)行連接通信的。
3) adb server
? ? ? 從圖中,我們同樣可以知道,server也是作為一個(gè)后臺(tái)的程序運(yùn)行在PC端的,他負(fù)責(zé)管理client進(jìn)程以及adb daemon之間的通信。
? ? ? ?當(dāng)一個(gè)server開啟的時(shí)候,他會(huì)自動(dòng)綁定并且監(jiān)聽(tīng)5037端口,接收client通過(guò)該端口發(fā)送過(guò)來(lái)的命令。同時(shí)server還會(huì)對(duì)5555-5585間的奇數(shù)端口進(jìn)行掃描,進(jìn)行對(duì)已連接設(shè)備的定位。
? ? ? ?完成了上面一大堆吧啦吧啦的掃盲,大家應(yīng)該知道了圖1的意思了吧,那么我們就要解決問(wèn)題了。
? ? ? 我們來(lái)看開發(fā)給我們的adb命令
? ? ? ?不知大家是否看到使用adb命令都要在前面輸入adb,譬如開發(fā)給的“adb pull /cache/recovery/ ./”這個(gè)命令就有adb在前面。那么為什么要在命令前面加上一個(gè)adb呢,原因在于如果我們不加adb,windows系統(tǒng)會(huì)默認(rèn)為對(duì)windows執(zhí)行命令,而不是通過(guò)ADB命令行工具對(duì)手機(jī)執(zhí)行操作命令。后面的“pull /cache/recovery/ ./”通過(guò)前面學(xué)習(xí)Linux命令結(jié)構(gòu)(linux命令結(jié)構(gòu)為command [options] [arguments...])大概可知道pull指的是命令動(dòng)作,后面那兩個(gè),指的其實(shí)就是參數(shù),/cache/recovery/指的是Pad設(shè)備的文件路徑,而./指的是當(dāng)前運(yùn)行命令行的路勁,譬如下面的提到的C:\Users\301001958這個(gè)路徑。
? ? ? 好了,繼續(xù)回到我們的裝比之路,剛開始的時(shí)候,我不小心把”adb pull /cache/recovery/ ./”打成了“adb pull /cache/recovery/./”,也就是,我沒(méi)有把中間的空格打上,結(jié)果彈出了這樣的提示,啊,真是瞎了我的眼……
? ? 于是,我馬上改過(guò)來(lái),修改成了“adb pull /cache/recovery/ ./”,結(jié)果還是彈出了一樣的提示。
? ? ?我擦,這怎么辦怎么辦,難道真的要裝比不成,反遭雷劈?別急,我們先來(lái)看看這里提示的意思,這里的這個(gè)remote的意思是指的遠(yuǎn)端設(shè)備,在這指的就是Pad,而object '/cache/recovery/' does not exist的意思就是說(shuō)Pad的/cache/recovery/這個(gè)文件夾對(duì)象不存在。
? ? ?這咋回事???怎么會(huì)就不存在呢?于是乎,我再進(jìn)入Recovery mode查看,得到的結(jié)果如下:
我擦,這怎么回事?明明有這個(gè)文件夾的存在,于是我再次開機(jī)在命令行輸入adb -help,驗(yàn)證一下這個(gè)adb命令的用法,結(jié)果吧啦吧啦的出現(xiàn)了一大坨黑色的字,看著都頭暈啊,不過(guò)還是讓我找到了想要的信息,如下圖:
? ? ? 看到了這里,我瞬間臉黑了,我靠,這完全就是跟我想的那樣沒(méi)錯(cuò)嘛,怎么就說(shuō)文件夾對(duì)象不存在呢。
? ? ? 于是我還是找上了大家最喜歡的——度娘。找了一番,找到了一個(gè)似乎有用的信息,如下圖:
? ? ?正如上面所說(shuō),難道是因?yàn)闆](méi)有文件夾沒(méi)有讀寫權(quán)限?于是,我又輸入了adb remount,得出結(jié)果如下:
? ? ? 額,看到這里,我不想說(shuō)話了,不過(guò)這里,已經(jīng)算是弄出了點(diǎn)端倪,大家應(yīng)該也知道了前面直接在Pad的系統(tǒng)里面復(fù)制提示無(wú)法復(fù)制了吧,最主要就是不夠權(quán)限的原因,因?yàn)橐坏┫到y(tǒng)運(yùn)行文件隨便被更改,系統(tǒng)就有可能出現(xiàn)運(yùn)行錯(cuò)誤或者崩潰。只是我竟天真的以為這里的root,指的是我們經(jīng)常用的那個(gè)一鍵root軟件,只要用軟件一鍵root了,就可以快樂(lè)的解決問(wèn)題了,可想而知,得到的結(jié)果依然是像是碰到了蜜蜂窩一樣,被蟄著千瘡百孔啊,面目全非……這些什么鳥一鍵root軟件,根本就無(wú)法root得了我們這些開發(fā)中的Pad嘛,還試了一大堆都不行,至于為什么,暫時(shí)我沒(méi)有深究,大家有空可以去研究研究。
? ? ?到了這里,我只想說(shuō):蓋倫,請(qǐng)給我一把大寶劍……
? ? ?無(wú)奈,問(wèn)題最終還是得要解決,于是我繼續(xù)再找度娘玩去了。
? ? ? 經(jīng)過(guò)了一番查找,我似乎終于找到了答案如何獲得root權(quán)限了,就是僅僅只需要用“adb root”這個(gè)命令就可以讓adb獲得root權(quán)限,二話不說(shuō),趕緊開干啊,輸入adb root,得出的結(jié)果是:adbd restart as root,我擦,藍(lán)瘦香菇,明明只需要幾個(gè)命令……就可以獲得root權(quán)限,我為什么能搞得那么復(fù)雜,我不行了,蓋倫,借你的大寶劍扶我起來(lái)……
? ? ? 但是似乎有一件很重要的事是,正因?yàn)槲仪懊嬗昧艘绘Iroot軟件,我才能在adb命令使用root權(quán)限,前面的功夫也并不是全是無(wú)用功,來(lái)到這里,我們就只需執(zhí)行最后一步就是用開發(fā)給的命令,把文件拖出來(lái),不過(guò),我把開發(fā)給的最后一個(gè)參數(shù)改了,也就是“./”這個(gè)參數(shù),改成了我自己電腦桌面的一個(gè)文件夾路徑,如我在桌面起了個(gè)叫做FileLog的文件夾,如我FileLog的文件夾路徑為C:\Users\301001958\Desktop\FileLog,那么我執(zhí)行的就是adb pull /cache/recovery/ C:\Users\301001958\Desktop\FileLog,然后按Enter執(zhí)行命令,文件就巴拉拉的復(fù)制到了我的FileLog文件夾里面,到這里問(wèn)題解決完畢。
? ? ? ?回顧整個(gè)過(guò)程,踩的坑著實(shí)不少,一個(gè)簡(jiǎn)簡(jiǎn)單單的命令,一個(gè)簡(jiǎn)簡(jiǎn)單單的操作,都能把自己搞死,不過(guò)在這整個(gè)過(guò)程里面,也是一個(gè)不斷擴(kuò)展知識(shí)的過(guò)程,也是一個(gè)不斷挑戰(zhàn)自我的過(guò)程,到最后的解決,是滿心的舒暢。
? ? ? ?這整個(gè)過(guò)程里,給我最大的感悟是,樂(lè)于助人,助的有時(shí)候不僅僅是別人,助的也是自己,因?yàn)樵谶@個(gè)過(guò)程中,我的知識(shí)獲得了拓展,獲得了成長(zhǎng),也獲得了成就感,獲得了興趣,用此文,希望能助正在踩坑的你,走出這個(gè)坑,不管是大坑還是小坑,又或者是神坑,在這個(gè)寫作分享的過(guò)程中,也讓我對(duì)整個(gè)知識(shí)面理解更全面更深了一步。
? ? ? ?文章寫得不是那么好,太長(zhǎng)了點(diǎn),請(qǐng)輕噴。
致正在踩坑的你我。 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2017.02.26 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?By BUG基