Android應(yīng)用程序的生命周期;
在大部份情況下,每個(gè)Android應(yīng)用都將運(yùn)行在自己的Linux進(jìn)程當(dāng)中。當(dāng)這個(gè)應(yīng)用的某些代碼需要執(zhí)行時(shí),進(jìn)程就會(huì)被創(chuàng)建,并且將保持運(yùn)行,直到該進(jìn)程不再需要,而系統(tǒng)需要釋放它所占用的內(nèi)存,為其他應(yīng)用所用時(shí),才停止。
Android一個(gè)重要并且特殊的特性就是,一個(gè)應(yīng)用的進(jìn)程的生命周期不是由應(yīng)用自身直接控制的,而是由系統(tǒng),根據(jù)運(yùn)行中的應(yīng)用的一些特征來(lái)決定的,包括:這些應(yīng)用對(duì)用戶的重要性、系統(tǒng)的全部可用內(nèi)存。
對(duì)于應(yīng)用開(kāi)發(fā)者來(lái)說(shuō),理解不同的應(yīng)用組件(特別是Activity、Service、Intent Receiver)對(duì)應(yīng)用進(jìn)程的生命周期的影響,這是非常重要的。如果沒(méi)有正確地使用這些組件,將會(huì)導(dǎo)致當(dāng)應(yīng)用正在處理重要的工作時(shí),進(jìn)程卻被系統(tǒng)消毀的后果。
對(duì)于進(jìn)程生命周期,一個(gè)普遍的錯(cuò)誤就是:當(dāng)一個(gè)Intent Receiver在它的onReceiveIntent()方法中,接收到一個(gè)intent后,就會(huì)從這個(gè)方法中返回。而一旦從這個(gè)方法返回后,系統(tǒng)將會(huì)認(rèn)為這個(gè)Intent Receiver不再處于活動(dòng)狀態(tài)了,也就會(huì)認(rèn)為它的宿主進(jìn)程不需要了(除非宿主進(jìn)程中還存在其它的應(yīng)用組件)。從而,系統(tǒng)隨時(shí)都會(huì)消毀這個(gè)進(jìn)程,收回內(nèi)存,并中止其中還在運(yùn)行的子線程。問(wèn)題的解決辦法就是,在IntentReceiver中,啟動(dòng)一個(gè)Service,這樣系統(tǒng)就會(huì)知道在這個(gè)進(jìn)程中,還有活動(dòng)的工作正在執(zhí)行。
為了決定在內(nèi)存不足情況下消毀哪個(gè)進(jìn)程,Android會(huì)根據(jù)這些進(jìn)程內(nèi)運(yùn)行的組件及這些組件的狀態(tài),把這些進(jìn)程劃分出一個(gè)“重要性層次”。這個(gè)層次按順序如下:
1、前端進(jìn)程是擁有一個(gè)顯示在屏幕最前端并與使用者做交互的Activity(它的onResume已被調(diào)用)的進(jìn)程,也可能是一個(gè)擁有正在運(yùn)行的IntentReceiver(它的onReceiveIntent()方法正在運(yùn)行)的進(jìn)程。在系統(tǒng)中,這種進(jìn)程是很少的,只有當(dāng)內(nèi)存低到不足于支持這些進(jìn)程的繼續(xù)運(yùn)行,才會(huì)將這些進(jìn)程消毀。通常這時(shí)候,設(shè)備已經(jīng)達(dá)到了需要進(jìn)行內(nèi)存整理的狀態(tài),為了保障用戶界面不停止響應(yīng),只能消毀這些進(jìn)程;
2、可視進(jìn)程是擁有一個(gè)用戶在屏幕上可見(jiàn)的,但并沒(méi)有在前端顯示的Activity(它的onPause已被調(diào)用)的進(jìn)程。例如:一個(gè)以對(duì)話框顯示的前端activity在屏幕上顯示,而它后面的上一級(jí)activity仍然是可見(jiàn)的。這樣的進(jìn)程是非常重要的,一般不會(huì)被消毀,除非為了保障所有的前端進(jìn)程正常運(yùn)行,才會(huì)被消毀。
3、服務(wù)進(jìn)程是擁有一個(gè)由startService()方法啟動(dòng)的Service的進(jìn)程。盡管這些進(jìn)程對(duì)于使用者是不可見(jiàn)的,但他們做的通常是使用者所關(guān)注的事情(如后臺(tái)MP3播放器或后臺(tái)上傳下載數(shù)據(jù)的網(wǎng)絡(luò)服務(wù))。因此,除非為了保障前端進(jìn)程和可視進(jìn)程的正常運(yùn)行,系統(tǒng)才會(huì)消毀這種進(jìn)程。
4、后臺(tái)進(jìn)程是擁有一個(gè)用戶不可見(jiàn)的Activity(onStop()方法已經(jīng)被調(diào)用)的進(jìn)程。這些進(jìn)程不直接影響用戶的體驗(yàn)。如果這些進(jìn)程正確地完成了自己的生命周期(詳細(xì)參考Activity類),系統(tǒng)會(huì)為了以上三種類型進(jìn)程,而隨時(shí)消毀這種進(jìn)程以釋放內(nèi)存。通常會(huì)有很多這樣的進(jìn)程在運(yùn)行著,因些這些進(jìn)程會(huì)被保存在一個(gè)LRU列表中,以保證在內(nèi)存不足時(shí),用戶最后看到的進(jìn)程將在最后才被消毀。
5、空進(jìn)程是那些不擁有任何活動(dòng)的應(yīng)用組件的進(jìn)程。保留這些進(jìn)程的唯一理由是,做為一個(gè)緩存,在它所屬的應(yīng)用的組件下一次需要時(shí),縮短啟動(dòng)的時(shí)間。同樣的,為了在這些緩存的空進(jìn)程和底層的核心緩存之間平衡系統(tǒng)資源,系統(tǒng)會(huì)經(jīng)常消毀這些空進(jìn)程。
當(dāng)要對(duì)一個(gè)進(jìn)程進(jìn)行分類時(shí),系統(tǒng)會(huì)選擇在這個(gè)進(jìn)程中所有活動(dòng)的組件中重要等級(jí)高的那個(gè)做為依據(jù)??梢詤⒖糀ctivity、Service、IntentReceiver文檔,了解這些組件如何影響進(jìn)程整個(gè)生命周期的更多細(xì)節(jié)。這些類的文檔都對(duì)他們?nèi)绾斡绊懰麄兯鶎俚膽?yīng)用的整個(gè)生命周期,做了詳細(xì)的描述。
針對(duì)
移動(dòng)端的網(wǎng)絡(luò)優(yōu)化,適用 Android,同樣適用于 iOS 和 H5
一個(gè)網(wǎng)絡(luò)請(qǐng)求可以簡(jiǎn)單分為連接服務(wù)器 -> 獲取數(shù)據(jù)兩個(gè)部分。
其中連接服務(wù)器前還包括 DNS 解析的過(guò)程;獲取數(shù)據(jù)后可能會(huì)對(duì)數(shù)據(jù)進(jìn)行緩存。
一、連接服務(wù)器優(yōu)化策略
1. 不用域名,用 IP 直連
省去 DNS 解析過(guò)程,DNS 全名 Domain Name System,解析意指根據(jù)域名得到其對(duì)應(yīng)的 IP 地址。 如 http://www.codekk.com 的域名解析結(jié)果就是 104.236.147.76。
首次域名解析一般需要幾百毫秒,可通過(guò)直接向 IP 而非域名請(qǐng)求,節(jié)省掉這部分時(shí)間,同時(shí)可以預(yù)防域名劫持等帶來(lái)的風(fēng)險(xiǎn)。
當(dāng)然為了安全和擴(kuò)展考慮,這個(gè) IP 可能是一個(gè)動(dòng)態(tài)更新的 IP 列表,并在 IP 不可用情況下通過(guò)域名訪問(wèn)。
2. 服務(wù)器合理部署
服務(wù)器多運(yùn)營(yíng)商多地部署,一般至少含三大運(yùn)營(yíng)商、南中北三地部署。
配合上面說(shuō)到的動(dòng)態(tài) IP 列表,支持優(yōu)先級(jí),每次根據(jù)地域、網(wǎng)絡(luò)類型等選擇最優(yōu)的服務(wù)器 IP 進(jìn)行連接。
對(duì)于服務(wù)器端還可以調(diào)優(yōu)服務(wù)器的 TCP 擁塞窗口大小、重傳超時(shí)時(shí)間(RTO)、大傳輸單元(MTU)等。
二、獲取數(shù)據(jù)優(yōu)化策略
1. 連接復(fù)用
節(jié)省連接建立時(shí)間,如開(kāi)啟 keep-alive。
Http 1.1 默認(rèn)啟動(dòng)了 keep-alive。對(duì)于 Android 來(lái)說(shuō)默認(rèn)情況下 HttpURLConnection 和 HttpClient 都開(kāi)啟了 keep-alive。只是 2.2 之前 HttpURLConnection 存在影響連接池的 Bug,具體可見(jiàn):Android HttpURLConnection 及 HttpClient 選擇
2. 請(qǐng)求合并
即將多個(gè)請(qǐng)求合并為一個(gè)進(jìn)行請(qǐng)求,比較常見(jiàn)的就是網(wǎng)頁(yè)中的 CSS Image Sprites。 如果某個(gè)頁(yè)面內(nèi)請(qǐng)求過(guò)多,也可以考慮做一定的請(qǐng)求合并。
3. 減小請(qǐng)求數(shù)據(jù)大小
(1) 對(duì)于 POST 請(qǐng)求,Body 可以做 Gzip 壓縮,如日志。
(2) 對(duì)請(qǐng)求頭進(jìn)行壓縮
這個(gè) Http 1.1 不支持,SPDY 及 Http 2.0 支持。 Http 1.1 可以通過(guò)服務(wù)端對(duì)前一個(gè)請(qǐng)求的請(qǐng)求頭進(jìn)行緩存,后面相同請(qǐng)求頭用 md5 之類的 id 來(lái)表示即可。
4. CDN 緩存靜態(tài)資源
緩存常見(jiàn)的圖片、JS、CSS 等靜態(tài)資源。
5. 減小返回?cái)?shù)據(jù)大小
(1) 壓縮
一般 API 數(shù)據(jù)使用 Gzip 壓縮,下圖是之前測(cè)試的 Gzip 壓縮前后對(duì)比圖。 android-http-compare
(2) 精簡(jiǎn)數(shù)據(jù)格式
如 JSON 代替 XML,WebP 代替其他圖片格式。關(guān)注公眾號(hào) codekk,回復(fù) 20 查看關(guān)于 WebP 的介紹。
(3) 對(duì)于不同的設(shè)備不同網(wǎng)絡(luò)返回不同的內(nèi)容 如不同分辨率圖片大小。
(4) 增量更新
需要數(shù)據(jù)更新時(shí),可考慮增量更新。如常見(jiàn)的服務(wù)端進(jìn)行 bsdiff,客戶端進(jìn)行 bspatch。
(5) 大文件下載
支持?jǐn)帱c(diǎn)續(xù)傳,并緩存 Http Resonse 的 ETag 標(biāo)識(shí),下次請(qǐng)求時(shí)帶上,從而確定是否數(shù)據(jù)改變過(guò),未改變則直接返回 304。
6. 數(shù)據(jù)緩存
緩存獲取到的數(shù)據(jù),在一定的有效時(shí)間內(nèi)再次請(qǐng)求可以直接從緩存讀取數(shù)據(jù)。
關(guān)于 Http 緩存規(guī)則 Grumoon 在 Volley 源碼解析最后雜談中有詳細(xì)介紹。
三、其他優(yōu)化手段
這類優(yōu)化方式在性能優(yōu)化系列總篇中已經(jīng)有過(guò)完整介紹
1. 預(yù)取
包括預(yù)連接、預(yù)取數(shù)據(jù)。
2. 分優(yōu)先級(jí)、延遲部分請(qǐng)求
將不重要的請(qǐng)求延遲,這樣既可以削峰減少并發(fā)、又可以和后面類似的請(qǐng)求做合并。
3. 多連接
對(duì)于較大文件,如大圖片、文件下載可考慮多連接。 需要控制請(qǐng)求的大并發(fā)量,畢竟
移動(dòng)端網(wǎng)絡(luò)受限。
四、監(jiān)控
優(yōu)化需要通過(guò)數(shù)據(jù)對(duì)比才能看出效果,所以監(jiān)控系統(tǒng)必不可少,通過(guò)前后端的數(shù)據(jù)監(jiān)控確定調(diào)優(yōu)效果。
當(dāng)前標(biāo)題:Android應(yīng)用程序的周期和網(wǎng)絡(luò)優(yōu)化
分享鏈接:http://www.rwnh.cn/news/150689.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、網(wǎng)站設(shè)計(jì)、ChatGPT、虛擬主機(jī)、移動(dòng)網(wǎng)站建設(shè)、App設(shè)計(jì)
廣告
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源:
創(chuàng)新互聯(lián)