adb的全名是Android調(diào)試橋,它充當(dāng)調(diào)試橋。Adb是Android SDK中的工具,使用此工具,您可以直接操作和管理Android模擬器或真實(shí)的Android設(shè)備(例如G1手機(jī))。
創(chuàng)新互聯(lián)主營建鄴網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,重慶APP開發(fā),建鄴h5微信小程序開發(fā)搭建,建鄴網(wǎng)站營銷推廣歡迎建鄴等地區(qū)企業(yè)咨詢
Android系統(tǒng)的adb的全名是Android Debug Bridge,在Android開發(fā)環(huán)境中,使用adb工具的前提是打開手機(jī)上的USB調(diào)試,然后通過數(shù)據(jù)線連接到計(jì)算機(jī)。通過adb,我們可以通過Eclipse中的DDMS(調(diào)試工具)輕松調(diào)試Android程序。Adb以一種特殊的方式工作,它監(jiān)視Socket TCP 5554和其他端口,以允許IDE和Qemu進(jìn)行通信,默認(rèn)情況下,adb將守護(hù)程序相關(guān)的網(wǎng)絡(luò)端口,因此,當(dāng)我們運(yùn)行Eclipse時,adb進(jìn)程將自動運(yùn)行。
Android Debug Bridge,Android調(diào)試橋接器,簡稱adb,是用于管理模擬器或真機(jī)狀態(tài)的萬能工具,采用了客戶端-服務(wù)器模型,包括三個部分:
ADB常用命令及其用法大全
adb工具環(huán)境配置和操作命令詳解
前端開發(fā)者必備的Nginx知識
使用UltraISO制作U盤啟動安裝系統(tǒng)的方法
安卓常用開發(fā)工具有:Eclipse?w/ADT、Android SDK?and?AVD?Manager、Android模擬器和實(shí)際移動設(shè)備、Android Debug Bridge(adb)等。
1.Eclipse?w/ADT
雖然Eclipse并非唯一可用于開發(fā)Android應(yīng)用的Java開發(fā)環(huán)境,但它是目前最歡迎的工具,有很大程度上是因?yàn)樗某杀竞艿停赓M(fèi)),但最主要的原因還是它與其他Android工具的強(qiáng)大組合功能。最典型的表現(xiàn)就是它與Android Development Tools(ADT)插件的組合(開發(fā)者可以通過Android網(wǎng)站下載ADT)。
2.Android SDK?and?AVD?Manager
這項(xiàng)SDK可提供多種重要的功能,它能管理不同版本的Android SDK,以及第三方附件、工具、設(shè)備驅(qū)動程序和文件。第二大功能就是管理用來安裝模擬器實(shí)體的Android Virtual Device配置(AVD)。
3.Android模擬器和實(shí)際移動設(shè)備
如果開發(fā)者創(chuàng)建完成了一款應(yīng)用程序,就必須針對自己鎖定的設(shè)備進(jìn)行測試。你可以將模擬器與AVD結(jié)合在一起模擬目標(biāo)移動設(shè)備的運(yùn)行環(huán)境,但更全面地進(jìn)行測試,你還是需要一個真正的移動設(shè)備,因?yàn)槟M器雖然功能強(qiáng)大,但它畢竟不是實(shí)際使用的手機(jī),用戶也不可能使用模擬器運(yùn)行應(yīng)用程序,所以實(shí)際移動設(shè)備也是測試環(huán)節(jié)必不可少的工具。
4.Android Debug Bridge(adb)
該工具可將其他工具接入模擬器和設(shè)備,它除了可以讓其他工具(游戲邦注:尤其是Eclipse ADT插件)功能生效以外,還可以使命令行上傳或下載文件,安裝或卸載程序包,通過進(jìn)入設(shè)備或模擬器的shell環(huán)境訪問許多其他功能。
5.Dalvik Debug Monitor Server(DDMS)
無論是通過獨(dú)立應(yīng)用程序還是Eclipse perspective訪問DDMS,它都能提供檢查、調(diào)試、與模擬器及設(shè)備實(shí)體交互的便利功能。開發(fā)者可使用DDMS檢查運(yùn)行程序和線程,探索文件系統(tǒng),搜集堆棧和其他內(nèi)存信息,附上調(diào)試器,甚至是抓取視頻截圖。通過模擬器,開發(fā)者還可以模擬電話接聽和發(fā)送SMS等狀態(tài)。
6.LogCat
LogCat是Android日志系統(tǒng)的名稱,你可以通過Eclipse、adb讀取LogCat數(shù)據(jù),它可以提供系統(tǒng)中相關(guān)事件的診斷信息。開發(fā)者可以由此將應(yīng)用程序的調(diào)試和診斷信息發(fā)送到LogCat。
7. Draw 9-Patch
Draw 9-Patch可助開發(fā)者更方便地完成應(yīng)用程序的圖形設(shè)計(jì),該工具支持開發(fā)者將傳統(tǒng)的PNG圖像文件轉(zhuǎn)化成更具靈活性、更能有效運(yùn)用于手機(jī)應(yīng)用開發(fā)過程的可擴(kuò)展圖像文件。這項(xiàng)工具可以在快速顯示效果的環(huán)境中簡化NinePatch文件的創(chuàng)建過程。
8.The Hierarchy Viewer
開發(fā)者可通過獨(dú)立應(yīng)用程序或者Eclipse perspective訪問The Hierarchy Viewer,它的作用是在運(yùn)行過程中查看程序的UI布局,提供了一個圖表顯示應(yīng)用程序布局和視圖層級的情況,開發(fā)者可依此判斷程序UI布局的存在問題。
1、Android Studio 谷歌原生的Android開發(fā)工具,有可視化的界面,xml配置比較方便,但是核心的代碼還是通過Java實(shí)現(xiàn),個人認(rèn)為比eclipse方便,不過上手起來還是有難度的。
2、APIcloud 國內(nèi)的一種云端開發(fā)方式,通過JSP調(diào)用已經(jīng)開發(fā)好的模塊,組成自己想要的功能,最後封裝成apk,上手簡單,模塊化強(qiáng),比如自己代碼能力不強(qiáng)可以直接調(diào)用別人寫好的開源代碼來實(shí)現(xiàn)功能,也是國內(nèi)很多開發(fā)都在用的方式。缺點(diǎn)是,代碼都是別人的,自己只是拿過來拼成一個軟件,在通用性、可擴(kuò)展性上還是沒有原生強(qiáng)大,但是勝在開發(fā)速度快。
3、Hbuilder 通過Html5語言寫成css樣式表,通過Android的Web service封裝成apk,可視化能力極強(qiáng),如今H5語言也在廣泛用於各個平臺,而且功能也比較強(qiáng)大,用這個寫成的軟件,在多種平臺都能共用,對Web service的支持也有一定的優(yōu)勢,不過上手也有一定難度,只是遠(yuǎn)遠(yuǎn)小於原生開發(fā)罷了。
智能手機(jī)最大的特性,就是可以通過APP實(shí)現(xiàn)各種各樣的功能。但是,很多時候我們的需求是瑣碎的,如果為每個功能都安裝與之匹配的APP顯然太過折騰。因此,整合類APP就成為了我們的首選目標(biāo)。
“實(shí)用工具箱”(可在酷安下載)就是一款符合上述要求的整合類APP,操作簡單,即點(diǎn)即用,唯一的小問題就是存在廣告插件。
這款應(yīng)用將170多個小工具劃入了日常、圖片、查詢、設(shè)備、輔助、提取、其他和趣味 游戲 8個大類下。
用戶可以根據(jù)需要,在相應(yīng)的大類中尋找目標(biāo)工具,還能將常用和喜歡的工具進(jìn)行收藏。
進(jìn)入該應(yīng)用的設(shè)置界面,可以將啟動界面設(shè)定為“顯示收藏”。
如此一來每次啟動這個APP就能直接顯示我們最常用(收藏的)的小功能入口了。
就功能而言,實(shí)用工具箱可以用“只有想不到,沒有辦不到”來形容。比如很多朋友都搞不清遠(yuǎn)房親戚的稱呼,找到“親戚稱呼計(jì)算”功能模塊,就能根據(jù)你的性別以及親屬之間的關(guān)系計(jì)算出準(zhǔn)確的稱呼了。
很多人都喜歡在全民K歌中錄歌,但如果事先沒有保存錄音文件,今后想下載自己的歌曲時也需要開通VIP會員,找到“全民K歌提取歌曲”功能模塊,輸入你自己歌曲的分享地址,點(diǎn)擊“獲取”按鈕就能生成相關(guān)歌曲的下載地址。同理,使用實(shí)用工具箱還能獲取包括微博、抖音等在內(nèi)的短視頻下載地址。
如果你想將手機(jī)上已安裝的應(yīng)用安裝包提取出來,只需找到“應(yīng)用管理”功能模塊,長按程序列表中的任意應(yīng)用,就能找到提取安裝包的選項(xiàng),輕松提取出APK文件。
實(shí)際上,上述功能只是實(shí)用工具箱的冰山一角,它的特色功能還包括圖片轉(zhuǎn)素描(圖片一鍵轉(zhuǎn)換成素描風(fēng)格)、圖片拼接(多圖橫縱向拼接)、藝術(shù)簽名(瀟灑的手寫簽名設(shè)計(jì))、自動滑屏器(解放雙手,自動滑屏)、LED滾動字幕(手持彈幕)、問答機(jī)器人(智能聊天機(jī)器人)、視頻提取音頻(提取視頻背景音樂)等等。
此外,實(shí)用工具箱還集成了透明屏幕、變音器、代碼雨壁紙、圖片隱寫術(shù)、隱藏圖制作等趣味功能,以及包括見縫插針、魔方、迷宮、2048、一個都不能死、數(shù)獨(dú)、黑白棋、圍住小紅點(diǎn)、切積木在內(nèi)的各種益智趣味 游戲 ,更支持淘寶、京東、拼多多等平臺的優(yōu)惠券查找領(lǐng)取功能。
toolbox是Android 自帶的提供shell命令的軟件。有點(diǎn)類似于busybox,但功能上好像弱很多。
其源碼可以從Android source code 中system/core/toolbox目錄下找到。
Android source code編譯完成后,toolbox被添加入rootfs中類似:/system/bin目錄下,用來提供必要的shell命令。但使用下來,覺得toolbox實(shí)在是功能非常有限。tools.h中通常只有以下一些命令:
(ls)(mount)(cat)(ps)(kill)(ln)(insmod)(rmmod)(lsmod)(ifconfig)(setconsole)(rm)(mkdir)(rmdir)(reboot)(getevent)(sendevent)(date)(wipe)(sync)(umount)(start)(stop)(notify)(cmp)(dmesg)(route)(hd)(dd)(df)(getprop)(setprop)(watchprops)(log)(sleep)(renice)(printenv)(smd)(chmod)(chown)(newfs_msdos)(netstat)(ioctl)(mv)(schedtop)(top)(iftop)(id)(vmstat)(nandread)(ionice)
且Android自帶的shell 也沒有tab補(bǔ)齊,按上鍵找之前的命令的功能。用起來實(shí)在不爽。
但我們可以添加busybox于其中。解決以上所有問題。
一.認(rèn)識android的架構(gòu)
Android其本質(zhì)就是在標(biāo)準(zhǔn)的Linux系統(tǒng)上增加了Java虛擬機(jī)Dalvik,并在Dalvik虛擬機(jī)上搭建了一個JAVA的application framework,所有的應(yīng)用程序都是基于JAVA的application framework之上。
android分為四個層,從高層到低層分別是應(yīng)用程序?qū)?、?yīng)用程序框架層、系統(tǒng)運(yùn)行庫層和linux核心層。
二.搭建環(huán)境
搭建開發(fā)環(huán)境
對國內(nèi)的開發(fā)者來說最痛苦的是無法去訪問android開發(fā)網(wǎng)站。為了更好的認(rèn)識世界,對程序員來說,會翻墻也是的一門技術(shù),帶你去領(lǐng)略墻外的世界,好了,不廢話了, 國內(nèi)開發(fā)者訪問(androiddevtools) 上面已經(jīng)有了所有你要的資源,同時可以下載到我們的主角framework
但是這樣的搭建只能去閱讀源代碼,我們無法去更進(jìn)一步去實(shí)現(xiàn)自己的rom,我們看到錘子的系統(tǒng)在早期的開放rom是自己從新實(shí)現(xiàn)了framework的代碼,現(xiàn)在看起來他成功了,所以我們還要去搭建android系統(tǒng)的源碼編譯環(huán)境。
搭建源碼編譯環(huán)境
三.開始主題
在一開始寫c程序的時候都有一個運(yùn)行的入口,比如
#include iostream
#include cmath
#include algorithm
using namespace std;
//這里的main就是應(yīng)用的入口
int main(int argc, const char * argv[]){
return 0;
}
在計(jì)算機(jī)網(wǎng)絡(luò)原理中我們用socket實(shí)現(xiàn)一個服務(wù)器端,不斷的接聽客戶端的訪問,而且他的代碼是這樣實(shí)現(xiàn)的:
#include winsock2.h
#pragma comment(lib, "WS2_32.lib")
#include stdio.h
void main()
{
WORD wVersionRequested;//版本號
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);//2.2版本的套接字
//加載套接字庫,如果失敗返回
err = WSAStartup(wVersionRequested, wsaData);
if (err != 0)
{
return;
}
//判斷高低字節(jié)是不是2,如果不是2.2的版本則退出
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2)
{
return;
}
//創(chuàng)建流式套接字,基于TCP(SOCK_STREAM)
SOCKET socSrv = socket(AF_INET, SOCK_STREAM, 0);
//Socket地址結(jié)構(gòu)體的創(chuàng)建
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//轉(zhuǎn)換Unsigned long型為網(wǎng)絡(luò)字節(jié)序格
addrSrv.sin_family = AF_INET;//指定地址簇
addrSrv.sin_port = htons(6000);
//指定端口號,除sin_family參數(shù)外,其它參數(shù)都是網(wǎng)絡(luò)字節(jié)序,因此需要轉(zhuǎn)換
//將套接字綁定到一個端口號和本地地址上
bind(socSrv, (SOCKADDR*)addrSrv, sizeof(SOCKADDR));//必須用sizeof,strlen不行
listen(socSrv, 5);
SOCKADDR_IN addrClient;//字義用來接收客戶端Socket的結(jié)構(gòu)體
int len = sizeof(SOCKADDR);//初始化參數(shù),這個參數(shù)必須進(jìn)行初始化,sizeof
//循環(huán)等待接受客戶端發(fā)送請求
while (1)
{
//等待客戶請求到來;當(dāng)請求到來后,接受連接請求,
//返回一個新的對應(yīng)于此次連接的套接字(accept)。
//此時程序在此發(fā)生阻塞
SOCKET sockConn = accept(socSrv, (SOCKADDR*)addrClient, len);
char sendBuf[100];
sprintf(sendBuf, "Welcome %s to JoyChou",
inet_ntoa(addrClient.sin_addr));//格式化輸出
//用返回的套接字和客戶端進(jìn)行通信
send(sockConn, sendBuf, strlen(sendBuf)+1, 0);//多發(fā)送一個字節(jié)
//接收數(shù)據(jù)
char recvBuf[100];
recv(sockConn, recvBuf, 100, 0);
printf("%s\\n", recvBuf);
closesocket(sockConn);
}
}
他采用了一個while死循環(huán)去監(jiān)聽客戶端的請求。
先上源代碼
public final class ActivityThread {
public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
Security.addProvider(new AndroidKeyStoreProvider());
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("pre-initialized");
Looper.prepareMainLooper();
//從中可以看到為app開辟了一個線程進(jìn)入了looper之中
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
看到源碼失望了,沒有一個while循環(huán)啊,其實(shí)用了他方法實(shí)現(xiàn)
//用一個looper的機(jī)制循環(huán)監(jiān)聽響應(yīng)
Looper.prepareMainLooper();
Looper.loop();
進(jìn)一步深入代碼
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
// 在這里看到了一個循環(huán)監(jiān)聽消息
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
Printer logging = me.mLogging;
if (logging != null) {
logging.println(" Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println(" Finished to " + msg.target + " " + msg.callback);
}
// Make sure that during the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycleUnchecked();
}
}