北京視聯(lián)動(dòng)力國(guó)際信息技術(shù)有限公司
崗位職責(zé):
1、負(fù)責(zé)Android機(jī)頂盒新功能的開發(fā)。
2、參與JNI接口的設(shè)計(jì)
3、參與Android機(jī)頂盒上層應(yīng)用程序框架的優(yōu)化和改進(jìn)。
4、撰寫相關(guān)技術(shù)文檔。
任職要求:
1、具有3年以上Android開發(fā)經(jīng)驗(yàn)。參加過兩個(gè)以上完整項(xiàng)目,并擔(dān)當(dāng)主力角色。
2、熟練掌握 Java語言,具有扎實(shí)的數(shù)據(jù)結(jié)構(gòu)、算法、軟件設(shè)計(jì)功底。
3、熟悉Android平臺(tái)的開發(fā)技術(shù)、系統(tǒng)框架原理和底層庫。
4、熟悉Http,TCP/IP,Socket等協(xié)議,掌握XML、JSON的解析。
5、對(duì)性能優(yōu)化、內(nèi)存優(yōu)化有一定經(jīng)驗(yàn)。
6、熟悉Linux/Unix系統(tǒng)操作、熟悉c/c++、有NDK開發(fā)經(jīng)驗(yàn)優(yōu)先。
7、有音視頻開發(fā)經(jīng)驗(yàn)者優(yōu)先。
8、熟悉機(jī)頂盒,有相關(guān)開發(fā)經(jīng)驗(yàn)優(yōu)先。
9、熟悉瀏覽器內(nèi)核WebKit優(yōu)先。
一、Android體系結(jié)構(gòu)
-
按層分析Android的體系結(jié)構(gòu)。
層次結(jié)構(gòu)圖
- Linux Kernel:負(fù)責(zé)硬件的驅(qū)動(dòng)程序、網(wǎng)絡(luò)、電源、系統(tǒng)安全以及內(nèi)存管理等功能。
- Libraries和Android Runtime:Libraries:即C/C++函數(shù)庫部分,大多數(shù)都是開放源代碼的函數(shù)庫,例如WebKit,該函數(shù)庫負(fù)責(zé)Android網(wǎng)頁瀏覽器的運(yùn)行,例如標(biāo)準(zhǔn)的C函數(shù)庫Libc、OpenSSL、SQLite等,當(dāng)然也包括支持游戲開發(fā)2D SGL和3D OpenGL | ES,在多媒體方面有MediaFramework框架來支持各種影音和圖形文件的播放與顯示,例如MPEG4、H.264、MP3、AAC、AMR、JPG和PNG等眾多的多媒體文件格式。Android的Runtime負(fù)責(zé)解釋和執(zhí)行生成的Dalvik格式的字節(jié)碼。
- ** Application Framework**:(應(yīng)用軟件架構(gòu)),Java應(yīng)用程序開發(fā)人員主要是使用該層封裝好的API進(jìn)行快速開發(fā)。
-
Applications:該層是Java的應(yīng)用程序?qū)樱珹ndroid內(nèi)置的Google Maps、E-mail、即時(shí)通信工具、瀏覽器、MP3播放器等處于該層,Java開發(fā)人員開發(fā)的程序也處于該層,而且和內(nèi)置的應(yīng)用程序具有平等的位置,可以調(diào)用內(nèi)置的應(yīng)用程序,也可以替換內(nèi)置的應(yīng)用程序。
優(yōu)點(diǎn):上面四個(gè)層次中,下層給上層服務(wù),上層支持下層支持,調(diào)用下層的服務(wù),這種嚴(yán)格的分層機(jī)制,為Android系統(tǒng)帶來很大的靈活性,穩(wěn)定性和可擴(kuò)展性。也利于不同層的開發(fā)人員專心于該層次的開發(fā)任務(wù)。
二、Http協(xié)議
引言
HTTP是一個(gè)屬于應(yīng)用層的面向?qū)ο蟮膮f(xié)議,由于其簡(jiǎn)捷、快速的方式,適用于分布式超媒體信息系統(tǒng)。它于1990年提出,經(jīng)過幾年的使用與發(fā)展,得到不斷地完善和擴(kuò)展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的規(guī)范化工作正在進(jìn)行之中,而且HTTP-NG(Next Generation of HTTP)的建議已經(jīng)提出。HTTP協(xié)議的主要特點(diǎn)可概括如下:
- 支持客戶/服務(wù)器模式。
- 簡(jiǎn)單快速:客戶向服務(wù)器請(qǐng)求服務(wù)時(shí),只需傳送請(qǐng)求方法和路徑。請(qǐng)求方法常用的有GET、HEAD、POST。每種方法規(guī)定了客戶與服務(wù)器聯(lián)系的類型不同。由于HTTP協(xié)議簡(jiǎn)單,使得HTTP服務(wù)器的程序規(guī)模小,因而通信速度很快。
- 靈活:HTTP允許傳輸任意類型的數(shù)據(jù)對(duì)象。正在傳輸?shù)念愋陀蒀ontent-Type加以標(biāo)記。
- 無連接:無連接的含義是限制每次連接只處理一個(gè)請(qǐng)求。服務(wù)器處理完客戶的請(qǐng)求,并收到客戶的應(yīng)答后,即斷開連接。采用這種方式可以節(jié)省傳輸時(shí)間。
- 無狀態(tài):HTTP協(xié)議是無狀態(tài)協(xié)議。無狀態(tài)是指協(xié)議對(duì)于事務(wù)處理沒有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能導(dǎo)致每次連接傳送的數(shù)據(jù)量增大。另一方面,在服務(wù)器不需要先前信息時(shí)它的應(yīng)答就較快。
一、HTTP協(xié)議詳解之URL篇
http(超文本傳輸協(xié)議)是一個(gè)基于請(qǐng)求與響應(yīng)模式的、無狀態(tài)的、應(yīng)用層的協(xié)議,?;赥CP的連接方式,HTTP1.1版本中給出一種持續(xù)連接的機(jī)制,絕大多數(shù)的Web開發(fā),都是構(gòu)建在HTTP協(xié)議之上的Web應(yīng)用。
HTTP URL (URL是一種特殊類型的URI,包含了用于查找某個(gè)資源的足夠的信息)的格式如下:[http://host[":"port][abs_path]
- http表示要通過HTTP協(xié)議來定位網(wǎng)絡(luò)資源;
- host表示合法的Internet主機(jī)域名或者IP地址;
- port指定一個(gè)端口號(hào),為空則使用缺省端口80;
- abs_path指定請(qǐng)求資源的URI;
如果URL中沒有給出abs_path,那么當(dāng)它作為請(qǐng)求URI時(shí),必須以“/”的形式給出,通常這個(gè)工作瀏覽器自動(dòng)幫我們完成。
- eg:輸入:
[www.android.cn]瀏覽器自動(dòng)轉(zhuǎn)換成[http://www.android.cn/]
二、HTTP協(xié)議詳解之請(qǐng)求篇
http請(qǐng)求由三部分組成,分別是:請(qǐng)求行、消息報(bào)頭、請(qǐng)求正文
- 請(qǐng)求行:以一個(gè)方法符號(hào)開頭,以空格分開,后面跟著請(qǐng)求的URI和協(xié)議的版本,格式如下:
-
Method Request-URI HTTP-Version CRLF:
- eg: GET https://www.android.com/ HTTP/1.1
- 其中 Method表示請(qǐng)求方法; --- GET
- Request-URI是一個(gè)統(tǒng)一資源標(biāo)識(shí)符;--- https://www.android.com/
- HTTP-Version表示請(qǐng)求的HTTP協(xié)議版本;--- HTTP/1.1
- CRLF表示回車和換行(除了作為結(jié)尾的CRLF外,不允許出現(xiàn)單獨(dú)的CR或LF字符)。
-
請(qǐng)求方法:(所有方法全為大寫)有多種,各個(gè)方法的解釋如下:
- GET:獲取Request-URI所標(biāo)識(shí)的資源;
- POST:在Request-URI所標(biāo)識(shí)的資源后附加新的數(shù)據(jù);
- HEAD:請(qǐng)求獲取由Request-URI所標(biāo)識(shí)的資源的響應(yīng)消息報(bào)頭
- PUT: 請(qǐng)求服務(wù)器存儲(chǔ)一個(gè)資源,并用Request-URI作為其標(biāo)識(shí);
- DELETE: 請(qǐng)求服務(wù)器刪除Request-URI所標(biāo)識(shí)的資源;
- TRACE: 請(qǐng)求服務(wù)器回送收到的請(qǐng)求信息,主要用于測(cè)試或診斷
- CONNECT: 保留將來使用;
- OPTIONS: 請(qǐng)求查詢服務(wù)器的性能,或者查詢與資源相關(guān)的選項(xiàng)和需求。
應(yīng)用舉例:
GET方法:在瀏覽器的地址欄中輸入網(wǎng)址的方式訪問網(wǎng)頁時(shí),瀏覽器采用GET方法向服務(wù)器獲取資源。
eg:
GET /form.html HTTP/1.1 (CRLF)POST方法:要求被請(qǐng)求服務(wù)器接受附在請(qǐng)求后面的數(shù)據(jù),常用于提交表單。
eg:
POST /reg.jsp HTTP/ (CRLF)
Accept:image/gif,image/x-xbit,... (CRLF)
...
HOST:www.android.cn (CRLF)
Content-Length:22 (CRLF)
Connection:Keep-Alive (CRLF)
Cache-Control:no-cache (CRLF)
(CRLF)//該CRLF表示消息報(bào)頭已經(jīng)結(jié)束,在此之前為消息報(bào)頭
user=jeffrey&pwd=1234//此行以下為提交的數(shù)據(jù)HEAD方法:與GET方法幾乎是一樣的,對(duì)于HEAD請(qǐng)求的回應(yīng)部分來說,它的HTTP頭部中包含的信息與通過GET請(qǐng)求所得到的信息是相同的。利用這個(gè)方法,不必傳輸整個(gè)資源內(nèi)容,就可以得到Request-URI所標(biāo)識(shí)的資源的信息。該方法常用于測(cè)試超鏈接的有效性,是否可以訪問,以及最近是否更新。
三、HTTP協(xié)議詳解之響應(yīng)篇
在接收和解釋請(qǐng)求消息后,服務(wù)器返回一個(gè)HTTP響應(yīng)消息。
HTTP響應(yīng)也是由三個(gè)部分組成,分別是:狀態(tài)行、消息報(bào)頭、響應(yīng)正文
-
狀態(tài)行格式如下:HTTP-Version Status-Code Reason-Phrase CRLF
- eg: HTTP/1.1 200 OK
- HTTP-Version表示服務(wù)器HTTP協(xié)議的版本;
- Status-Code表示服務(wù)器發(fā)回的響應(yīng)狀態(tài)代碼;
- Reason-Phrase表示狀態(tài)代碼的文本描述。
狀態(tài)代碼有三位數(shù)字組成,第一個(gè)數(shù)字定義了響應(yīng)的類別,且有五種可能取值:
1xx:指示信息--表示請(qǐng)求已接收,繼續(xù)處理;
2xx:成功--表示請(qǐng)求已被成功接收、理解、接受;
3xx:重定向--要完成請(qǐng)求必須進(jìn)行更進(jìn)一步的操作;
4xx:客戶端錯(cuò)誤--請(qǐng)求有語法錯(cuò)誤或請(qǐng)求無法實(shí)現(xiàn);
5xx:服務(wù)器端錯(cuò)誤--服務(wù)器未能實(shí)現(xiàn)合法的;
-
請(qǐng)求常見狀態(tài)代碼、狀態(tài)描述、說明:
- 200 OK
//客戶端請(qǐng)求成功 - 400 Bad Request
//客戶端請(qǐng)求有語法錯(cuò)誤,不能被服務(wù)器所理解 - 401 Unauthorized
//請(qǐng)求未經(jīng)授權(quán),這個(gè)狀態(tài)代碼必須和WWW-Authenticate報(bào)頭域一起使用 - 403 Forbidden
//服務(wù)器收到請(qǐng)求,但是拒絕提供服務(wù) - 404 Not Found
//請(qǐng)求資源不存在eg:輸入了錯(cuò)誤的URL - 500 Internal Server Error
//服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤 - 503 Server Unavailable
//服務(wù)器當(dāng)前不能處理客戶端的請(qǐng)求,一段時(shí)間后可能恢復(fù)正常
- 200 OK
響應(yīng)報(bào)頭后述
響應(yīng)正文就是服務(wù)器返回的資源的內(nèi)容
四、HTTP協(xié)議詳解之消息報(bào)頭篇
HTTP消息由客戶端到服務(wù)器的請(qǐng)求和服務(wù)器到客戶端的響應(yīng)組成。
請(qǐng)求消息和響應(yīng)消息都是由以下內(nèi)容組成:
- 開始行(對(duì)于請(qǐng)求消息,開始行就是請(qǐng)求行,對(duì)于響應(yīng)消息,開始行就是狀態(tài)行)
- 消息報(bào)頭(可選)
- 空行(只有CRLF的行)
- 消息正文(可選)組成
HTTP消息報(bào)頭包括普通報(bào)頭、請(qǐng)求報(bào)頭、響應(yīng)報(bào)頭、實(shí)體報(bào)頭。
每一個(gè)報(bào)頭域都是由名字+“:”+空格+值 組成,消息報(bào)頭域的名字是大小寫無關(guān)的。(eg:
Host: www.baidu.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.6
)
1. 普通報(bào)頭
在普通報(bào)頭中,有少數(shù)報(bào)頭域用于所有的請(qǐng)求和響應(yīng)消息,但并不用于被傳輸?shù)膶?shí)體,只用于傳輸?shù)南ⅰ?br>
eg:Cache-Control 用于指定緩存指令,緩存指令是單向的(響應(yīng)中出現(xiàn)的緩存指令在請(qǐng)求中未必會(huì)出現(xiàn)),且是獨(dú)立的(一個(gè)消息的緩存指令不會(huì)影響另一個(gè)消息處理的緩存機(jī)制),HTTP1.0使用的類似的報(bào)頭域?yàn)镻ragma。
請(qǐng)求時(shí)的緩存指令包括:no-cache(用于指示請(qǐng)求或響應(yīng)消息不能緩存)、no-store、max-age、max-stale、min-fresh、only-if-cached;
響應(yīng)時(shí)的緩存指令包括:public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age、s-maxage。
eg:為了指示IE瀏覽器(客戶端)不要緩存頁面,服務(wù)器端的JSP程序可以編寫如下:
response.sehHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");作用相當(dāng)于上述代碼,通常兩者合用。這句代碼將在發(fā)送的響應(yīng)消息中設(shè)置普通報(bào)頭域:Cache-Control:no-cache。
-
Date普通報(bào)頭域
表示消息產(chǎn)生的日期和時(shí)間。 -
Connection普通報(bào)頭域
允許發(fā)送指定連接的選項(xiàng)。例如:指定連接是連續(xù),或者指定“close”選項(xiàng),通知服務(wù)器,在響應(yīng)完成后,關(guān)閉連接。
2. 請(qǐng)求報(bào)頭
請(qǐng)求報(bào)頭允許客戶端向服務(wù)器端傳遞請(qǐng)求的附加信息以及客戶端自身的信息。
常用的請(qǐng)求報(bào)頭:
- Accept
Accept請(qǐng)求報(bào)頭域用于指定客戶端接受哪些類型的信息。
eg:
Accept:image/gif,表明客戶端希望接受GIF圖象格式的資源;
Accept:text/html,表明客戶端希望接受html文本。 - Accept-Charset
Accept-Charset請(qǐng)求報(bào)頭域用于指定客戶端接受的字符集。
eg:
Accept-Charset:iso-8859-1,gb2312。如果在請(qǐng)求消息中沒有設(shè)置這個(gè)域,缺省是任何字符集都可以接受。 - Accept-Encoding
Accept-Encoding請(qǐng)求報(bào)頭域類似于Accept,但是它是用于指定可接受的內(nèi)容編碼。
eg:
Accept-Encoding:gzip.deflate.如果請(qǐng)求消息中沒有設(shè)置這個(gè)域服務(wù)器假定客戶端對(duì)各種內(nèi)容編碼都可以接受。 - Accept-Language
Accept-Language請(qǐng)求報(bào)頭域類似于Accept,但是它是用于指定一種自然語言。
eg:
Accept-Language:zh-cn.如果請(qǐng)求消息中沒有設(shè)置這個(gè)報(bào)頭域,服務(wù)器假定客戶端對(duì)各種語言都可以接受。 - Authorization
Authorization請(qǐng)求報(bào)頭域主要用于證明客戶端有權(quán)查看某個(gè)資源。當(dāng)瀏覽器訪問一個(gè)頁面時(shí),如果收到服務(wù)器的響應(yīng)代碼為401(未授權(quán)),可以發(fā)送一個(gè)包含Authorization請(qǐng)求報(bào)頭域的請(qǐng)求,要求服務(wù)器對(duì)其進(jìn)行驗(yàn)證。Host(發(fā)送請(qǐng)求時(shí),該報(bào)頭域是必需的)Host請(qǐng)求報(bào)頭域主要用于指定被請(qǐng)求資源的Internet主機(jī)和端口號(hào),它通常從HTTP URL中提取出來的。
eg:
我們?cè)跒g覽器中輸入:[http://www.android.cn/index.html]
瀏覽器發(fā)送的請(qǐng)求消息中,就會(huì)包含Host請(qǐng)求報(bào)頭域,如下:
Host:[www.android.cn] 此處使用缺省端口號(hào)80,若指定了端口號(hào),則變成:Host:[www.guet.edu.cn]:指定端口號(hào) - User-Agent
我們上網(wǎng)登陸論壇的時(shí)候,往往會(huì)看到一些歡迎信息,其中列出了你的操作系統(tǒng)的名稱和版本,你所使用的瀏覽器的名稱和版本,這往往讓很多人感到很神奇,實(shí)際上,服務(wù)器應(yīng)用程序就是從User-Agent這個(gè)請(qǐng)求報(bào)頭域中獲取到這些信息。User-Agent請(qǐng)求報(bào)頭域允許客戶端將它的操作系統(tǒng)、瀏覽器和其它屬性告訴服務(wù)器。不過,這個(gè)報(bào)頭域不是必需的,如果我們自己編寫一個(gè)瀏覽器,不使用User-Agent請(qǐng)求報(bào)頭域,那么服務(wù)器端就無法得知我們的信息了。
請(qǐng)求報(bào)頭舉例:
GET /form.html HTTP/1.1 (CRLF)
Accept:image/gif,image/x-xbitmap,image/jpeg,application/x-shockwave-flash,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,/ (CRLF)
Accept-Language:zh-cn (CRLF)
Accept-Encoding:gzip,deflate (CRLF)
If-Modified-Since:Wed,05 Jan 2007 11:21:25 GMT (CRLF)
If-None-Match:W/"80b1a4c018f3c41:8317" (CRLF)
User-Agent:Mozilla/4.0(compatible;MSIE6.0;Windows NT 5.0) (CRLF)
Host:www.android.cn (CRLF)
Connection:Keep-Alive (CRLF)
(CRLF)
3. 響應(yīng)報(bào)頭
響應(yīng)報(bào)頭允許服務(wù)器傳遞不能放在狀態(tài)行中的附加響應(yīng)信息,以及關(guān)于服務(wù)器的信息和對(duì)Request-URI所標(biāo)識(shí)的資源進(jìn)行下一步訪問的信息。
常用的響應(yīng)報(bào)頭:
- Location
Location響應(yīng)報(bào)頭域用于重定向接受者到一個(gè)新的位置。Location響應(yīng)報(bào)頭域常用在更換域名的時(shí)候。 - Server
Server響應(yīng)報(bào)頭域包含了服務(wù)器用來處理請(qǐng)求的軟件信息。與User-Agent請(qǐng)求報(bào)頭域是相對(duì)應(yīng)的。下面是Server響應(yīng)報(bào)頭域的一個(gè)例子:
Server:Apache-Coyote/1.1 - WWW-Authenticate
WWW-Authenticate響應(yīng)報(bào)頭域必須被包含在401(未授權(quán)的)響應(yīng)消息中,客戶端收到401響應(yīng)消息時(shí)候,并發(fā)送Authorization報(bào)頭域請(qǐng)求服務(wù)器對(duì)其進(jìn)行驗(yàn)證時(shí),服務(wù)端響應(yīng)報(bào)頭就包含該報(bào)頭域。
eg:
WWW-Authenticate:Basic realm="Basic Auth Test!"//可以看出服務(wù)器對(duì)請(qǐng)求資源采用的是基本驗(yàn)證機(jī)制
4. 實(shí)體報(bào)頭
請(qǐng)求和響應(yīng)消息都可以傳送一個(gè)實(shí)體。一個(gè)實(shí)體由實(shí)體報(bào)頭域和實(shí)體正文組成,但并不是說實(shí)體報(bào)頭域和實(shí)體正文要在一起發(fā)送,可以只發(fā)送實(shí)體報(bào)頭域。實(shí)體報(bào)頭定義了關(guān)于實(shí)體正文(eg:有無實(shí)體正文)和請(qǐng)求所標(biāo)識(shí)的資源的元信息。
常用的實(shí)體報(bào)頭:
- Content-Encoding
Content-Encoding實(shí)體報(bào)頭域被用作媒體類型的修飾符,它的值指示了已經(jīng)被應(yīng)用到實(shí)體正文的附加內(nèi)容的編碼,因而要獲得Content-Type報(bào)頭域中所引用的媒體類型,必須采用相應(yīng)的解碼機(jī)制。Content-Encoding這樣用于記錄文檔的壓縮方法。
eg:
Content-Encoding:gzip - Content-Language
Content-Language實(shí)體報(bào)頭域描述了資源所用的自然語言。沒有設(shè)置該域則認(rèn)為實(shí)體內(nèi)容將提供給所有的語言閱讀者。
eg:
Content-Language:da - Content-Length
Content-Length實(shí)體報(bào)頭域用于指明實(shí)體正文的長(zhǎng)度,以字節(jié)方式存儲(chǔ)的十進(jìn)制數(shù)字來表示。 - Content-Type
Content-Type實(shí)體報(bào)頭域用于指明發(fā)送給接收者的實(shí)體正文的媒體類型。
eg:
Content-Type:text/html;charset=ISO-8859-1
Content-Type:text/html;charset=GB2312 - Last-Modified
Last-Modified實(shí)體報(bào)頭域用于指示資源的最后修改日期和時(shí)間。 - Expires
Expires實(shí)體報(bào)頭域給出響應(yīng)過期的日期和時(shí)間。為了讓代理服務(wù)器或?yàn)g覽器在一段時(shí)間以后更新緩存中(再次訪問曾訪問過的頁面時(shí),直接從緩存中加載,縮短響應(yīng)時(shí)間和降低服務(wù)器負(fù)載)的頁面,我們可以使用Expires實(shí)體報(bào)頭域指定頁面過期的時(shí)間。
eg:
Expires:Thu,15 Sep 2006 16:23:12 GMT
HTTP1.1的客戶端和緩存必須將其他非法的日期格式(包括0)看作已經(jīng)過期。eg:為了讓瀏覽器不要緩存頁面,我們也可以利用Expires實(shí)體報(bào)頭域,設(shè)置為0,jsp中程序如下:response.setDateHeader("Expires","0");
三、TCP/IP協(xié)議
協(xié)議中存在各式各樣的內(nèi)容。從電纜的規(guī)格到IP地址的選定方法、尋找異地用戶的方法、雙方建立通信的順序,以及Web頁面顯示需要處理的步驟。像這樣把與互聯(lián)網(wǎng)相關(guān)聯(lián)的協(xié)議集合起來總稱為TCP/IP協(xié)議。
TCP/IP協(xié)議族按層次分為:應(yīng)用層、傳輸層、網(wǎng)絡(luò)層和數(shù)據(jù)鏈路層。
應(yīng)用層
應(yīng)用層決定了向用戶提供應(yīng)用服務(wù)時(shí)通信的活動(dòng)。
FTP(File Transfer Protocol 文件傳輸協(xié)議)和DNS(Domain Name System 域名系統(tǒng))。
HTTP協(xié)議也處于該層。傳輸層
傳輸層對(duì)上層應(yīng)用層,提供處于網(wǎng)絡(luò)連接中的兩臺(tái)計(jì)算機(jī)之間的數(shù)據(jù)傳輸。
在傳輸層有兩個(gè)性質(zhì)不同的協(xié)議:TCP(Transmission Control Protocol 傳輸控制協(xié)議) 和 UDP(User Data Protocol 用戶數(shù)據(jù)報(bào)協(xié)議)。網(wǎng)絡(luò)層
網(wǎng)絡(luò)層用來處理在網(wǎng)絡(luò)上流動(dòng)的數(shù)據(jù)包。數(shù)據(jù)包時(shí)網(wǎng)絡(luò)傳輸?shù)淖钚?shù)據(jù)單位。該層規(guī)定了通過怎樣的路徑(所謂傳輸路線)到達(dá)對(duì)方計(jì)算機(jī),并把數(shù)據(jù)傳送給對(duì)方。鏈路層(又名數(shù)據(jù)鏈路層,網(wǎng)絡(luò)接口層)
用來處理連接網(wǎng)絡(luò)的硬件部分。
與HTTP關(guān)系密切的協(xié)議:IP、TCP和DNS
負(fù)責(zé)傳輸?shù)腎P協(xié)議
按層次分,IP(Internet Protocol)網(wǎng)絡(luò)協(xié)議位于網(wǎng)絡(luò)層。-
確??煽啃缘腡CP協(xié)議
按層次分,TCP位于傳輸層,提供可靠的字節(jié)流服務(wù)。為了方便傳輸,將大塊數(shù)據(jù)分割成以報(bào)文段(segment)為單位的數(shù)據(jù)包進(jìn)行管理。TCP協(xié)議能夠確認(rèn)數(shù)據(jù)最終是否送達(dá)到對(duì)方。- TCP協(xié)議采用了三次握手(three-way-handshaking)策略。
發(fā)送端首先發(fā)送一個(gè)帶SYN(synchronize)標(biāo)志的數(shù)據(jù)包給對(duì)方。接收端收到后,回傳一個(gè)帶有SYN/ACK(acknowledgement)標(biāo)志的數(shù)據(jù)包以示表達(dá)確認(rèn)信息。最后發(fā)送端再回傳一個(gè)帶ACK標(biāo)志的數(shù)據(jù)包,代表握手結(jié)束。除了三次握手,TCP協(xié)議還有其他各種手段來保證通信的可靠性。
- TCP協(xié)議采用了三次握手(three-way-handshaking)策略。
四、Socket協(xié)議
我們知道兩個(gè)進(jìn)程如果需要進(jìn)行通訊最基本的一個(gè)前提能能夠唯一的標(biāo)示一個(gè)進(jìn)程,在本地進(jìn)程通訊中我們可以使用PID來唯一標(biāo)示一個(gè)進(jìn)程,但PID只在本地唯一,網(wǎng)絡(luò)中的兩個(gè)進(jìn)程PID沖突幾率很大,這時(shí)候我們需要另辟它徑了,我們知道IP層的ip地址可以唯一標(biāo)示主機(jī),而TCP層協(xié)議和端口號(hào)可以唯一標(biāo)示主機(jī)的一個(gè)進(jìn)程,這樣我們可以利用ip地址+協(xié)議+端口號(hào)唯一標(biāo)示網(wǎng)絡(luò)中的一個(gè)進(jìn)程。能夠唯一標(biāo)示網(wǎng)絡(luò)中的進(jìn)程后,它們就可以利用socket進(jìn)行通信了.
- 什么是socket呢?
我們經(jīng)常把socket翻譯為套接字,socket是在應(yīng)用層和傳輸層之間的一個(gè)抽象層,它把TCP/IP層復(fù)雜的操作抽象為幾個(gè)簡(jiǎn)單的接口供應(yīng)用層調(diào)用已實(shí)現(xiàn)進(jìn)程在網(wǎng)絡(luò)中通信。
Socket起源于UNIX,在Unix一切皆文件哲學(xué)的思想下,socket是一種"打開—讀/寫—關(guān)閉"模式的實(shí)現(xiàn),服務(wù)器和客戶端各自維護(hù)一個(gè)"文件",在建立連接打開后,可以向自己文件寫入內(nèi)容供對(duì)方讀取或者讀取對(duì)方內(nèi)容,通訊結(jié)束時(shí)關(guān)閉文件。
五、C++
- Java沒有顯式指針,而在C++中卻可以用。
- Java是主動(dòng)多態(tài)的,Java會(huì)主動(dòng)地從祖父類、祖祖父類……追溯至最高一級(jí)父類,然后從上至下開始尋找并調(diào)用。C++不會(huì)主動(dòng)使用多態(tài)。
- Java是隱式繼承的,你不說你是誰的子類,那么你就是Object的子類,甚至你說你不是類都不可以,你必須是類,然后才能談到實(shí)例化的對(duì)象C++卻把話都說明白了,你繼承誰就繼承誰,繼承多個(gè)都可以,你什么都不說那么就不繼承。實(shí)際上C++禁止這么做。原因前面已經(jīng)說過了,C++是被動(dòng)多態(tài)的。你不用virtual去修飾基類的成員函數(shù),程序執(zhí)行時(shí)函數(shù)調(diào)用就不會(huì)自動(dòng)調(diào)到派生類。
- Java有接口,C++中卻沒有。
- Java是單根繼承(Single inheritance)的,但是允許一個(gè)類實(shí)現(xiàn)多個(gè)接口。C++卻支持多繼承。
- Java和C++最顯著的區(qū)別體現(xiàn)在對(duì)象的處理上。Java中,對(duì)象變量在內(nèi)部被當(dāng)作指針處理。Java文獻(xiàn)指出將對(duì)象變量作為引用,不過它們與C++中的引用并不完全相同。所謂引用,就是一個(gè)介于指針和變量之間的東西。
- Java中所有的函數(shù)都與類相關(guān),沒有全局變量和非成員函數(shù),而C++卻支持這些。因?yàn)镃++當(dāng)中可以沒有類,即使沒有類,程序依然執(zhí)行得好好的,并且在程序設(shè)計(jì)的功能很少的時(shí)候,我就喜歡這么干。偶爾面向過程編程,又有什么不好呢?
- C++中,你使用的動(dòng)態(tài)內(nèi)存怎么用就怎么還,Java中你不用管,Java包含一個(gè)垃圾收集系統(tǒng),作為運(yùn)行時(shí)庫的一部分。
- Java有很緊湊的異常處理機(jī)制,而C++稍微顯得草率了一些。但是這并不代表C++異常處理機(jī)制不強(qiáng)大,因?yàn)镴ava只能拋出Throwable子類的異常,C++卻什么都可以。
- Java標(biāo)準(zhǔn)庫又是Java龐大的體現(xiàn),涵蓋了國(guó)際化、網(wǎng)絡(luò)化、數(shù)學(xué)、聲音、Web應(yīng)用和服務(wù)以及數(shù)據(jù)庫等。你可以說Java語言在JSP、JavaScipt、網(wǎng)絡(luò)編程、分布計(jì)算交易管理應(yīng)用、Java ME應(yīng)用、Web應(yīng)用上風(fēng)光無限,說Java是一門小巧的語言,但是Java的小巧也主要就小巧這些方面。
六、JNI接口
Java本地接口 (JNI)是一個(gè)編程框架使得運(yùn)行在Java虛擬機(jī)上的Java程序調(diào)用或者被調(diào)用特定于本機(jī)硬件與操作系統(tǒng)的用其它語言(C、C++或匯編語言等)編寫的程序。
JNI允許用本地代碼來解決純粹用Java編程不能解決的平臺(tái)相關(guān)的特性。也用于改造已存在的其它語言寫的應(yīng)用程序,供Java程序訪問。許多使用了JNI的標(biāo)準(zhǔn)庫提供了文件I/O與其它功能。標(biāo)準(zhǔn)庫中性能敏感或平臺(tái)敏感的API實(shí)現(xiàn)允許所有Java應(yīng)用程序安全且平臺(tái)獨(dú)立地訪問這些功能。
JNI框架使得本地方法可以訪問Java對(duì)象,就如同Java程序訪問這些本地對(duì)象。本地方法可以創(chuàng)建Java對(duì)象,然后檢查、使用這些對(duì)象執(zhí)行任務(wù)。本地方法也可以檢查并使用由Java程序創(chuàng)建的對(duì)象。
斯:系統(tǒng)提供接口,使Java語言編寫的方法能與其他語言之間編寫的方法相互調(diào)用。
七、NDK開發(fā)
為了應(yīng)用的安全性,會(huì)將一些復(fù)雜的邏輯[算法通過本地代碼(C或C++)來實(shí)現(xiàn),然后打包成so動(dòng)態(tài)庫文件,并提供Java接口供應(yīng)用層調(diào)用。比如百度開放平臺(tái)提供的定位服務(wù)、搜索服務(wù)、LBS服務(wù)、推送服務(wù)的Android SDK,除了Java接口的jar包之外,還有一個(gè).so文件,這個(gè)so就是實(shí)現(xiàn)了Java層定義的native接口的動(dòng)態(tài)庫。
八、Android性能優(yōu)化
渲染機(jī)制
Android系統(tǒng)每隔16ms發(fā)出VSYNC信號(hào),觸發(fā)對(duì)UI進(jìn)行渲染,如果每次渲染都成功,這樣就能夠達(dá)到流暢的畫面所需要的60fps,為了能夠?qū)崿F(xiàn)60fps,這意味著程序的大多數(shù)操作都必須在16ms內(nèi)完成。
我們可以通過一些工具來定位問題,比如可以使用HierarchyViewer來查找Activity中的布局是否過于復(fù)雜,也可以使用手機(jī)設(shè)置里面的開發(fā)者選項(xiàng),打開Show GPU Overdraw等選項(xiàng)進(jìn)行觀察。你還可以使用TraceView來觀察CPU的執(zhí)行情況,更加快捷的找到性能瓶頸。
- Understanding Overdraw(過度繪制)
Overdraw(過度繪制)描述的是屏幕上的某個(gè)像素在同一幀的時(shí)間內(nèi)被繪制了多次。在多層次的UI結(jié)構(gòu)里面,如果不可見的UI也在做繪制的操作,這就會(huì)導(dǎo)致某些像素區(qū)域被繪制了多次。這就浪費(fèi)大量的CPU以及GPU資源。
我們可以通過手機(jī)設(shè)置里面的開發(fā)者選項(xiàng),打開Show GPU Overdraw的選項(xiàng),可以觀察UI上的Overdraw情況。
藍(lán)色,淡綠,淡紅,深紅代表了4種不同程度的Overdraw情況,我們的目標(biāo)就是盡量減少紅色Overdraw,看到更多的藍(lán)色區(qū)域。
Overdraw有時(shí)候是因?yàn)槟愕腢I布局存在大量重疊的部分,還有的時(shí)候是因?yàn)榉潜仨毜闹丿B背景。例如某個(gè)Activity有一個(gè)背景,然后里面的Layout又有自己的背景,同時(shí)子View又分別有自己的背景。僅僅是通過移除非必須的背景圖片,這就能夠減少大量的紅色Overdraw區(qū)域,增加藍(lán)色區(qū)域的占比。這一措施能夠顯著提升程序性能。
- Understanding VSYNC
- Refresh Rate:代表了屏幕在一秒內(nèi)刷新屏幕的次數(shù),這取決于硬件的固定參數(shù),例如60Hz。
- Frame Rate:代表了GPU在一秒內(nèi)繪制操作的幀數(shù),例如30fps,60fps。
通常來說,幀率超過刷新頻率只是一種理想的狀況,在超過60fps的情況下,GPU所產(chǎn)生的幀數(shù)據(jù)會(huì)因?yàn)榈却齎SYNC的刷新信息而被Hold住,這樣能夠保持每次刷新都有實(shí)際的新的數(shù)據(jù)可以顯示。但是我們遇到更多的情況是幀率小于刷新頻率。
-
Tool:Profile GPU Rendering---GPU 渲染工具
打開手機(jī)里面的開發(fā)者選項(xiàng),選擇Profile GPU Rendering,選中On screen as bars的選項(xiàng)。
選擇了這樣以后,我們可以在手機(jī)畫面上看到豐富的GPU繪制圖形信息,分別關(guān)于StatusBar,NavBar,激活的程序Activity區(qū)域的GPU Rending信息。
隨著界面的刷新,界面上會(huì)滾動(dòng)顯示垂直的柱狀圖來表示每幀畫面所需要渲染的時(shí)間,柱狀圖越高表示花費(fèi)的渲染時(shí)間越長(zhǎng)。
中間有一根綠色的橫線,代表16ms,我們需要確保每一幀花費(fèi)的總時(shí)間都低于這條橫線,這樣才能夠避免出現(xiàn)卡頓的問題。
每一條柱狀線都包含三部分,藍(lán)色代表測(cè)量繪制Display List的時(shí)間,紅色代表OpenGL渲染Display List所需要的時(shí)間,黃色代表CPU等待GPU處理的時(shí)間。
開發(fā)app的性能目標(biāo)就是保持60fps,這意味著每一幀你只有16ms=1000/60的時(shí)間來處理所有的任務(wù)。 DisplayList
Android需要把XML布局文件轉(zhuǎn)換成GPU能夠識(shí)別并繪制的對(duì)象。這個(gè)操作是在DisplayList的幫助下完成的。DisplayList持有所有將要交給GPU繪制到屏幕上的數(shù)據(jù)信息。
內(nèi)存優(yōu)化
-
Memory Churn內(nèi)存抖動(dòng),內(nèi)存抖動(dòng)是因?yàn)榇罅康膶?duì)象被創(chuàng)建又在短時(shí)間內(nèi)馬上被釋放。
瞬間產(chǎn)生大量的對(duì)象會(huì)嚴(yán)重占用Young Generation的內(nèi)存區(qū)域,當(dāng)達(dá)到閥值,剩余空間不夠的時(shí)候,也會(huì)觸發(fā)GC。即使每次分配的對(duì)象占用了很少的內(nèi)存,但是他們疊加在一起會(huì)增加Heap的壓力,從而觸發(fā)更多其他類型的GC。這個(gè)操作有可能會(huì)影響到幀率,并使得用戶感知到性能問題。
解決上面的問題有簡(jiǎn)潔直觀方法,如果你在Memory Monitor里面查看到短時(shí)間發(fā)生了多次內(nèi)存的漲跌,這意味著很有可能發(fā)生了內(nèi)存抖動(dòng)。
Paste_Image.png
同時(shí)我們還可以通過Allocation Tracker來查看在短時(shí)間內(nèi),同一個(gè)棧中不斷進(jìn)出的相同對(duì)象。這是內(nèi)存抖動(dòng)的典型信號(hào)之一。
例如,你需要避免在for循環(huán)里面分配對(duì)象占用內(nèi)存,需要嘗試把對(duì)象的創(chuàng)建移到循環(huán)體之外,自定義View中的onDraw方法也需要引起注意,每次屏幕發(fā)生繪制以及動(dòng)畫執(zhí)行過程中,onDraw方法都會(huì)被調(diào)用到,避免在onDraw方法里面執(zhí)行復(fù)雜的操作,避免創(chuàng)建對(duì)象。對(duì)于那些無法避免需要?jiǎng)?chuàng)建對(duì)象的情況,我們可以考慮對(duì)象池模型,通過對(duì)象池來解決頻繁創(chuàng)建與銷毀的問題,但是這里需要注意結(jié)束使用之后,需要手動(dòng)釋放對(duì)象池中的對(duì)象。
通過Memory Monitor我們可以查看到內(nèi)存的占用情況,每一次瞬間的內(nèi)存降低都是因?yàn)榇藭r(shí)發(fā)生了GC操作,如果在短時(shí)間內(nèi)發(fā)生大量的內(nèi)存上漲與降低的事件,這說明很有可能這里有性能問題。我們還可以通過Heap and Allocation Tracker工具來查看此時(shí)內(nèi)存中分配的到底有哪些對(duì)象。
-
Memory Leaks內(nèi)存泄漏
內(nèi)存泄漏指的是那些程序不再使用的對(duì)象無法被GC識(shí)別,這樣就導(dǎo)致這個(gè)對(duì)象一直留在內(nèi)存當(dāng)中,占用了寶貴的內(nèi)存空間。顯然,這還使得每級(jí)Generation的內(nèi)存區(qū)域可用空間變小,GC就會(huì)更容易被觸發(fā),從而引起性能問題。(leakcanary框架使用)
首先你需要在activity處于前臺(tái)的時(shí)候使用Heap Tool獲取一份當(dāng)前狀態(tài)的內(nèi)存快照,然后你需要?jiǎng)?chuàng)建一個(gè)幾乎不這么占用內(nèi)存的空白activity用來給前一個(gè)Activity進(jìn)行跳轉(zhuǎn),其次在跳轉(zhuǎn)到這個(gè)空白的activity的時(shí)候主動(dòng)調(diào)用System.gc()方法來確保觸發(fā)一個(gè)GC操作。最后,如果前面這個(gè)activity的內(nèi)存都有全部正確釋放,那么在空白activity被啟動(dòng)之后的內(nèi)存快照中應(yīng)該不會(huì)有前面那個(gè)activity中的任何對(duì)象了。
如果你發(fā)現(xiàn)在空白activity的內(nèi)存快照中有一些可疑的沒有被釋放的對(duì)象存在,那么接下去就應(yīng)該使用Alocation Track Tool來仔細(xì)查找具體的可疑對(duì)象。我們可以從空白activity開始監(jiān)聽,啟動(dòng)到觀察activity,然后再回到空白activity結(jié)束監(jiān)聽。這樣操作以后,我們可以仔細(xì)觀察那些對(duì)象,找出內(nèi)存泄漏的真兇。
為了尋找內(nèi)存的性能問題,Android Studio提供了工具來幫助開發(fā)者。- Memory Monitor:查看整個(gè)app所占用的內(nèi)存,以及發(fā)生GC的時(shí)刻,短時(shí)間內(nèi)發(fā)生大量的GC操作是一個(gè)危險(xiǎn)的信號(hào)。
- Allocation Tracker:使用此工具來追蹤內(nèi)存的分配,前面有提到過。
- Heap Tool:查看當(dāng)前內(nèi)存快照,便于對(duì)比分析哪些對(duì)象有可能是泄漏了的,請(qǐng)參考前面的Case。







