adb的全稱為Android Debug Bridge,就是起到調試橋的作用。通過adb我們可以在IDE中方面通過DDMS來調試Android程序,說白了就是debug工具。 adb的工作方式比較特殊,采用監聽Socket TCP 5554等端口的方式讓IDE和Qemu通訊,默認情況下adb會daemon相關的網絡端口,所以當我們運行IDE時adb進程就會自動運行。
公司主營業務:成都做網站、成都網站設計、移動網站開發等業務。幫助企業客戶真正實現互聯網宣傳,提高企業的競爭能力。創新互聯是一支青春激揚、勤奮敬業、活力青春激揚、勤奮敬業、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業文化,感謝他們對我們的高要求,感謝他們從不同領域給我們帶來的挑戰,讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創新互聯推出興隆免費做網站回饋大家。
adb的全稱為Android Debug Bridge,就是起到調試橋的作用。通過adb我們可以在Eclipse中方面通過DDMS來調試Android程序,說白了就是debug工具。 adb的工作方式比較特殊,采用監聽Socket TCP 5554等端口的方式讓IDE和Qemu通訊,默認情況下adb會daemon相關的網絡端口,所以當我們運行Eclipse時adb進程就會自動運行。
對于安卓開發與測試來說就像一把“瑞士軍刀”
ADB本身是Android手機開發時的調試工具,但是也可以用來作為手機管理工具。
基本上現在的豌豆莢(豌豆莢會自動在手機上安裝其APP-靜默安裝)、360手機助手、qq手機助手對手機的管理功能都是通過ADB來實現。
ADB的管理功能需要手機打開調試選項,這為手機管理提供了方便,同時也造成了安全隱患。
因為ADB工具可以實現查看手機內容、向手機寫入文件、給手機安裝軟件等功能,這些都不需要root權限。
當我們打開手機的調試選項,并使用USB線將手機連接到PC時,不僅僅是手機管理工具可以控制手機,只要調用ADB命令,任何PC端的程序都可以訪問手機內容。
假設有一個運行在PC端的間諜程序,那么就很容易檢測到手機與PC的連接,而且只要一條很簡單的命令"adb.exe shell ls /"就可以列出手機根目錄下的所有文件了。
其實如果打開了手機的調試選項,那么手機連接到PC后就是在“裸奔",手機中的所有信息都可以被PC端抓取,其實這也就是現在流行的手機管理工具的基本原理。
所以如果需要保護手機上的私密信息,那么最好謹慎打開手機的USB調試選項
一.認識android的架構
Android其本質就是在標準的Linux系統上增加了Java虛擬機Dalvik,并在Dalvik虛擬機上搭建了一個JAVA的application framework,所有的應用程序都是基于JAVA的application framework之上。
android分為四個層,從高層到低層分別是應用程序層、應用程序框架層、系統運行庫層和linux核心層。
二.搭建環境
搭建開發環境
對國內的開發者來說最痛苦的是無法去訪問android開發網站。為了更好的認識世界,對程序員來說,會翻墻也是的一門技術,帶你去領略墻外的世界,好了,不廢話了, 國內開發者訪問(androiddevtools) 上面已經有了所有你要的資源,同時可以下載到我們的主角framework
但是這樣的搭建只能去閱讀源代碼,我們無法去更進一步去實現自己的rom,我們看到錘子的系統在早期的開放rom是自己從新實現了framework的代碼,現在看起來他成功了,所以我們還要去搭建android系統的源碼編譯環境。
搭建源碼編譯環境
三.開始主題
在一開始寫c程序的時候都有一個運行的入口,比如
#include iostream
#include cmath
#include algorithm
using namespace std;
//這里的main就是應用的入口
int main(int argc, const char * argv[]){
return 0;
}
在計算機網絡原理中我們用socket實現一個服務器端,不斷的接聽客戶端的訪問,而且他的代碼是這樣實現的:
#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;
}
//判斷高低字節是不是2,如果不是2.2的版本則退出
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2)
{
return;
}
//創建流式套接字,基于TCP(SOCK_STREAM)
SOCKET socSrv = socket(AF_INET, SOCK_STREAM, 0);
//Socket地址結構體的創建
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//轉換Unsigned long型為網絡字節序格
addrSrv.sin_family = AF_INET;//指定地址簇
addrSrv.sin_port = htons(6000);
//指定端口號,除sin_family參數外,其它參數都是網絡字節序,因此需要轉換
//將套接字綁定到一個端口號和本地地址上
bind(socSrv, (SOCKADDR*)addrSrv, sizeof(SOCKADDR));//必須用sizeof,strlen不行
listen(socSrv, 5);
SOCKADDR_IN addrClient;//字義用來接收客戶端Socket的結構體
int len = sizeof(SOCKADDR);//初始化參數,這個參數必須進行初始化,sizeof
//循環等待接受客戶端發送請求
while (1)
{
//等待客戶請求到來;當請求到來后,接受連接請求,
//返回一個新的對應于此次連接的套接字(accept)。
//此時程序在此發生阻塞
SOCKET sockConn = accept(socSrv, (SOCKADDR*)addrClient, len);
char sendBuf[100];
sprintf(sendBuf, "Welcome %s to JoyChou",
inet_ntoa(addrClient.sin_addr));//格式化輸出
//用返回的套接字和客戶端進行通信
send(sockConn, sendBuf, strlen(sendBuf)+1, 0);//多發送一個字節
//接收數據
char recvBuf[100];
recv(sockConn, recvBuf, 100, 0);
printf("%s\\n", recvBuf);
closesocket(sockConn);
}
}
他采用了一個while死循環去監聽客戶端的請求。
先上源代碼
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開辟了一個線程進入了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循環啊,其實用了他方法實現
//用一個looper的機制循環監聽響應
Looper.prepareMainLooper();
Looper.loop();
進一步深入代碼
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();
// 在這里看到了一個循環監聽消息
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();
}
}
幀,是視頻的一個基本概念,表示一張畫面,如上面的翻頁動畫書中的一頁,就是一幀。一個視頻就是由許許多多幀組成的。
幀率,即單位時間內幀的數量,單位為:幀/秒 或fps(frames per second)。一秒內包含多少張圖片,圖片越多,畫面越順滑,過渡越自然。 幀率的一般以下幾個典型值:
24/25 fps:1秒 24/25 幀,一般的電影幀率。
30/60 fps:1秒 30/60 幀,游戲的幀率,30幀可以接受,60幀會感覺更加流暢逼真。
85 fps以上人眼基本無法察覺出來了,所以更高的幀率在視頻里沒有太大意義。
這里我們只講常用到的兩種色彩空間。
RGB的顏色模式應該是我們最熟悉的一種,在現在的電子設備中應用廣泛。通過R G B三種基礎色,可以混合出所有的顏色。
這里著重講一下YUV,這種色彩空間并不是我們熟悉的。這是一種亮度與色度分離的色彩格式。
早期的電視都是黑白的,即只有亮度值,即Y。有了彩色電視以后,加入了UV兩種色度,形成現在的YUV,也叫YCbCr。
Y:亮度,就是灰度值。除了表示亮度信號外,還含有較多的綠色通道量。
U:藍色通道與亮度的差值。
V:紅色通道與亮度的差值。
音頻數據的承載方式最常用的是 脈沖編碼調制 ,即 PCM 。
在自然界中,聲音是連續不斷的,是一種模擬信號,那怎樣才能把聲音保存下來呢?那就是把聲音數字化,即轉換為數字信號。
我們知道聲音是一種波,有自己的振幅和頻率,那么要保存聲音,就要保存聲音在各個時間點上的振幅。
而數字信號并不能連續保存所有時間點的振幅,事實上,并不需要保存連續的信號,就可以還原到人耳可接受的聲音。
根據奈奎斯特采樣定理:為了不失真地恢復模擬信號,采樣頻率應該不小于模擬信號頻譜中最高頻率的2倍。
根據以上分析,PCM的采集步驟分為以下步驟:
采樣率,即采樣的頻率。
上面提到,采樣率要大于原聲波頻率的2倍,人耳能聽到的最高頻率為20kHz,所以為了滿足人耳的聽覺要求,采樣率至少為40kHz,通常為44.1kHz,更高的通常為48kHz。
采樣位數,涉及到上面提到的振幅量化。波形振幅在模擬信號上也是連續的樣本值,而在數字信號中,信號一般是不連續的,所以模擬信號量化以后,只能取一個近似的整數值,為了記錄這些振幅值,采樣器會采用一個固定的位數來記錄這些振幅值,通常有8位、16位、32位。
位數越多,記錄的值越準確,還原度越高。
最后就是編碼了。由于數字信號是由0,1組成的,因此,需要將幅度值轉換為一系列0和1進行存儲,也就是編碼,最后得到的數據就是數字信號:一串0和1組成的數據。
整個過程如下:
聲道數,是指支持能不同發聲(注意是不同聲音)的音響的個數。 單聲道:1個聲道
雙聲道:2個聲道
立體聲道:默認為2個聲道
立體聲道(4聲道):4個聲道
碼率,是指一個數據流中每秒鐘能通過的信息量,單位bps(bit per second)
碼率 = 采樣率 * 采樣位數 * 聲道數
這里的編碼和上面音頻中提到的編碼不是同個概念,而是指壓縮編碼。
我們知道,在計算機的世界中,一切都是0和1組成的,音頻和視頻數據也不例外。由于音視頻的數據量龐大,如果按照裸流數據存儲的話,那將需要耗費非常大的存儲空間,也不利于傳送。而音視頻中,其實包含了大量0和1的重復數據,因此可以通過一定的算法來壓縮這些0和1的數據。
特別在視頻中,由于畫面是逐漸過渡的,因此整個視頻中,包含了大量畫面/像素的重復,這正好提供了非常大的壓縮空間。
因此,編碼可以大大減小音視頻數據的大小,讓音視頻更容易存儲和傳送。
視頻編碼格式有很多,比如H26x系列和MPEG系列的編碼,這些編碼格式都是為了適應時代發展而出現的。
其中,H26x(1/2/3/4/5)系列由ITU(International Telecommunication Union)國際電傳視訊聯盟主導
MPEG(1/2/3/4)系列由MPEG(Moving Picture Experts Group, ISO旗下的組織)主導。
當然,他們也有聯合制定的編碼標準,那就是現在主流的編碼格式H264,當然還有下一代更先進的壓縮編碼標準H265。
H264是目前最主流的視頻編碼標準,所以我們后續的文章中主要以該編碼格式為基準。
H264由ITU和MPEG共同定制,屬于MPEG-4第十部分內容。
我們已經知道,視頻是由一幀一幀畫面構成的,但是在視頻的數據中,并不是真正按照一幀一幀原始數據保存下來的(如果這樣,壓縮編碼就沒有意義了)。
H264會根據一段時間內,畫面的變化情況,選取一幀畫面作為完整編碼,下一幀只記錄與上一幀完整數據的差別,是一個動態壓縮的過程。
在H264中,三種類型的幀數據分別為
I幀:幀內編碼幀。就是一個完整幀。
P幀:前向預測編碼幀。是一個非完整幀,通過參考前面的I幀或P幀生成。
B幀:雙向預測內插編碼幀。參考前后圖像幀編碼生成。B幀依賴其前最近的一個I幀或P幀及其后最近的一個P幀。
全稱:Group of picture。指一組變化不大的視頻幀。
GOP的第一幀成為關鍵幀:IDR
IDR都是I幀,可以防止一幀解碼出錯,導致后面所有幀解碼出錯的問題。當解碼器在解碼到IDR的時候,會將之前的參考幀清空,重新開始一個新的序列,這樣,即便前面一幀解碼出現重大錯誤,也不會蔓延到后面的數據中。
DTS全稱:Decoding Time Stamp。標示讀入內存中數據流在什么時候開始送入解碼器中進行解碼。也就是解碼順序的時間戳。
PTS全稱:Presentation Time Stamp。用于標示解碼后的視頻幀什么時候被顯示出來。
前面我們介紹了RGB和YUV兩種圖像色彩空間。H264采用的是YUV。
YUV存儲方式分為兩大類:planar 和 packed。
planar如下:
packed如下:
上面說過,由于人眼對色度敏感度低,所以可以通過省略一些色度信息,即亮度共用一些色度信息,進而節省存儲空間。因此,planar又區分了以下幾種格式:YUV444、 YUV422、YUV420。
YUV 4:4:4采樣,每一個Y對應一組UV分量。
YUV 4:2:2采樣,每兩個Y共用一組UV分量。
YUV 4:2:0采樣,每四個Y共用一組UV分量。
其中,最常用的就是YUV420。
YUV420屬于planar存儲方式,但是又分兩種類型:
YUV420P:三平面存儲。數據組成為YYYYYYYYUUVV(如I420)或YYYYYYYYVVUU(如YV12)。
YUV420SP:兩平面存儲。分為兩種類型YYYYYYYYUVUV(如NV12)或YYYYYYYYVUVU(如NV21)
原始的PCM音頻數據也是非常大的數據量,因此也需要對其進行壓縮編碼。
和視頻編碼一樣,音頻也有許多的編碼格式,如:WAV、MP3、WMA、APE、FLAC等等,音樂發燒友應該對這些格式非常熟悉,特別是后兩種無損壓縮格式。
但是,我們今天的主角不是他們,而是另外一個叫AAC的壓縮格式。
AAC是新一代的音頻有損壓縮技術,一種高壓縮比的音頻壓縮算法。在MP4視頻中的音頻數據,大多數時候都是采用AAC壓縮格式。
AAC格式主要分為兩種:ADIF、ADTS。
ADIF:Audio Data Interchange Format。音頻數據交換格式。這種格式的特征是可以確定的找到這個音頻數據的開始,不需進行在音頻數據流中間開始的解碼,即它的解碼必須在明確定義的開始處進行。這種格式常用在磁盤文件中。
ADTS:Audio Data Transport Stream。音頻數據傳輸流。這種格式的特征是它是一個有同步字的比特流,解碼可以在這個流中任何位置開始。它的特征類似于mp3數據流格式。
ADIF數據格式:
ADTS 一幀 數據格式(中間部分,左右省略號為前后數據幀):
AAC內部結構也不再贅述,可以參考AAC 文件解析及解碼流程
細心的讀者可能已經發現,前面我們介紹的各種音視頻的編碼格式,沒有一種是我們平時使用到的視頻格式,比如:mp4、rmvb、avi、mkv、mov...
沒錯,這些我們熟悉的視頻格式,其實是包裹了音視頻編碼數據的容器,用來把以特定編碼標準編碼的視頻流和音頻流混在一起,成為一個文件。
例如:mp4支持H264、H265等視頻編碼和AAC、MP3等音頻編碼。
我們在一些播放器中會看到,有硬解碼和軟解碼兩種播放形式給我們選擇,但是我們大部分時候并不能感覺出他們的區別,對于普通用戶來說,只要能播放就行了。
那么他們內部究竟有什么區別呢?
在手機或者PC上,都會有CPU、GPU或者解碼器等硬件。通常,我們的計算都是在CPU上進行的,也就是我們軟件的執行芯片,而GPU主要負責畫面的顯示(是一種硬件加速)。
所謂軟解碼,就是指利用CPU的計算能力來解碼,通常如果CPU的能力不是很強的時候,一則解碼速度會比較慢,二則手機可能出現發熱現象。但是,由于使用統一的算法,兼容性會很好。
硬解碼,指的是利用手機上專門的解碼芯片來加速解碼。通常硬解碼的解碼速度會快很多,但是由于硬解碼由各個廠家實現,質量參差不齊,非常容易出現兼容性問題。
MediaCodec 是Android 4.1(api 16)版本引入的編解碼接口,是所有想在Android上開發音視頻的開發人員繞不開的坑。
由于Android碎片化嚴重,雖然經過多年的發展,Android硬解已經有了很大改觀,但實際上各個廠家實現不同, 還是會有一些意想不到的坑。
相對于FFmpeg,Android原生硬解碼還是相對容易入門一些,所以接下來,我將會從MediaCodec入手,講解如何實現視頻的編解碼,以及引入OpenGL實現對視頻的編輯,最后才引入FFmpeg來實現軟解,算是一個比較常規的音視頻開發入門流程吧。
佳音北大青鳥安卓培訓學校是一家由移動互聯網的資深專業人士共同創立的培訓學員。
佳音北大青鳥自成立之日起,就以促進和發展移動互聯網化為已任,專注進行佳音android培訓和佳音ios培訓。
如今許多大學生都對Android和IOS等移動開發感興趣,有自學的有進入像我們佳音北大青鳥這樣的培訓機構,今天就由佳音北大青鳥的老師來給基礎薄弱的同學一點建議。
自學Android開發怎么快速入門:首先,想學習的同學需要一個明晰自己的目標,其實android開發也會分為應用、游戲、底層等等,每種不同的方向需要學習不同的知識。
比如要做APP的話j2me、web、sql等等都要學習,最好是從這些基礎的支持開始,后面才有發展,佳音北大青鳥老師推薦大家先多看看java方面的教程。
可進入佳音北大青鳥教學視頻進行學習。
要做游戲的話當然要在opengl、線性代數這些基礎上再開始,做底層的話可能更多的涉及到嵌入式的驅動、LINUX方面,對不同的平臺不同的硬件配置要有了解才能做好底層工作,這一部分可能對C基礎、匯編、硬件的原理等等要求很扎實,要通常要多年的積累,熟悉kernel、文件系統、各類協議等等。
當然細分還有很多,這里不一一舉例了,還是推薦去把基礎學扎實了,當有料之后,看一下android相應的一些工具書等等,很快就能上手了,多多和技術論壇的朋友進行互動,寫程序沒有取巧的,在這些基礎之上再去培訓機構系統的跟著老師強化學習一下,和老師做一些開發項目,佳音北大青鳥安卓培訓學校講師都是具備多年項目實戰背景、以及多年的佳音android培訓和佳音IOS培訓教學經驗。
授課過程中,會針對不同類型的學員靈活轉變教學方式,學員在掌握理論基礎的同時,能夠在實際操作中靈活運用。
如果你想從事andriod手機軟件開發,那么你需要擁有這些東西:
1、最基本的是需要懂得用Java語言和XML知識。
2、掌握了這兩種語言后再裝個Eclipse和Android
SDK,
就可以做開發了。當然,還得學Android特有的API的用法。Java和XML只是編程基礎。
不管怎樣,手機軟件開發最低的入門條件是:
1.
熟悉《數據結構》
2.
熟悉多任務操作系統
3.
精通C語言
4.
略知通信協議,比如ISDN協議中呼叫建立和呼叫拆除過程。
如果你想跳過這些繁瑣的步驟,想走捷徑,這也不是不可能的,你可以通過在線應用開發平臺進行開發,比如通過應用之星(appstar.com.cn)平臺,它對開發者無技術門檻,人人都能開發app。
以下內容是對Google Android TV文檔的翻譯,可能存在錯誤,請讀者以官方文檔為準
官方地址
在文檔中Google對Android TV的提出了許多要求,如果你只是使用它的一些UI元素,你可以不用太注意這些要求。
官方地址 鏡像地址
TV應用在手機和平板電腦上使用相同的項目結構。這意味著你可以修改已經存在的應用使其在電視設備上運行或者在你已知的Android知識上創建新的應用。這部分內容主要是準備開發環境和開發TV應用的一些最低要求。(開發TV應用和手機應用本質是一致的,下面的一些要求只是你要使用到一些Google的庫(Leanback support)或者要將應用在GooglePlay上線,否則,要求不必遵守)
Supported Media Formats
DRM
android.drm
ExoPlayer
android.media.MediaPlayer
這一部分主要關于如何修改一個已存在的Android項目或者創建一個新的項目。
下面是讓app在電視設備上運行的主要部分:
1.Activity for TV,在manifest中聲明一個activity。
2.TV Support Libraries
1.SDK tools version 24.0.0 或者更高
2.SDK with android5.0 或者更高
3.創建或更新項目(如果你要修改已存在的Android項目應該是該項目的target為5.0或者更高)
可以兼容到API17
如果一個應用打算運行在電視設備上它必須在manifest文件中聲明一個TV activity。如下:
如果設置required屬性為true,你的APP在設備上將只運行leanback ui。
運行在TV設備上的應用不需要通過觸摸屏幕來輸入。
v17 leanback library 為電視應用程序提供用戶界面部件,特別是用于媒體播放的應用程序。
v7 recyclerview library
v7 cardview library
在完成上述步驟之后,是時候開始為大屏幕構建應用程序了!檢查這些額外的主題,以幫助您建立您的應用程序的電視:
構建電視播放應用
幫助用戶搜索內容
Building TV Games
Building TV Channels
網站名稱:android快速入門,安卓快速入門
文章網址:http://m.newbst.com/article30/dssisso.html
成都網站建設公司_創新互聯,為您提供全網營銷推廣、網站設計公司、定制開發、ChatGPT、網站制作、網站內鏈
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯