天天看點

一文讀懂Android程序及TCP動态心跳保活

一直以來,<code>APP程序保活</code>都是 <code>各軟體提供商</code> 和 <code>個人開發者</code> 頭疼的問題。畢竟一切的商業模式都建立在使用者對APP的使用上,是以<code>保證APP程序的喚醒</code>,<code>提升使用者的使用時間</code>,便是軟體提供商和個人開發者的永恒追求。

面對國内<code>GCM</code>(Google Cloud Messaging)推送服務不可用,也<code>未出現一個統一市場PUSH平台</code>的現狀。早期的第三方軟體一般通過維持一個<code>終端</code>與<code>遠端伺服器</code>之間的<code>TCP長連接配接</code>,達到<code>PUSH拉活</code>和<code>消息及時送達</code>的目的。

而為了維持這個<code>TCP長連接配接</code>不斷開,前提條件就是保證自己APP的背景服務程序,不會被殺死(因為隻有活着的終端程序才能定期與遠端伺服器通信,保證長連接配接不斷連)。

是以在Android釋出的早期,各種技術論壇和GitHub出現了<code>五花八門、各顯神通</code>的<code>App程序保活</code>方案;如今随着Android系統的逐漸完善,各種程序保活方案不斷受到限制,想要做到Android程序保活已經不太容易。

一般來說,<code>Android程序保活</code>主要有以下兩方面工作:

程序保活:保持<code>程序不被系統殺死</code>或<code>程序被殺後可以重新拉起</code>。

早期Android,對于背景運作的<code>Service服務程序</code>限制較小,第三方軟體<code>保證自己APP背景服務程序長時間運作</code>相對容易,但仍然是有被系統殺死的可能。

這個階段随着APP的不斷增多,許多第三方APP開始利用系統漏洞(早期的Android系統尚不完善,可利用的漏洞較多),在<code>APP進入背景</code>或<code>系統準備休眠時</code>,通過各種<code>所謂的黑科技</code>(實際為流氓手段)保證自己的<code>APP程序不被殺死</code>,甚至<code>阻止系統休眠</code>。

伴随随着這類軟體的不斷增多,最終造成的結果是,使用者側<code>手機卡頓</code>、<code>待機時間短</code>、<code>耗電量增加</code>。

TCP保活:保證<code>終端</code>與<code>遠端伺服器</code>之間的<code>TCP長連接配接</code>不斷連。

在<code>App程序保活</code>的基礎上,一般通過使用Android系統<code>RCT時鐘 Alarm</code>每5~10分鐘喚醒一次系統,并發送一條隻有幾個位元組的<code>TCP保活消息</code>,來維持<code>終端</code>與<code>遠端伺服器</code>之間的<code>TCP長連接配接</code>不斷開。

這裡簡單回顧一下,Android早期<code>App程序保活</code>的各種方案。

通過Service的onStartCommand方法中傳回 <code>START_STICKY</code>:

當Service的onStartCommand方法傳回 <code>START_STICKY</code> 時,若目前Service因記憶體不足被系統清理掉,待記憶體再次空閑時,系統将會嘗試重新建立此Service,一旦建立成功後将回調onStartCommand方法,但其中的Intent将是NULL。

1像素透明Activity程序保活:

監測到Android系統息屏時,<code>啟動一個1像素的前台透明Activity</code>,欺騙系統,使其認為該應用為一個前台應用而不會被清理(據說淘寶早期就使用過這種方案)。

開啟前台服務:

利用系統漏洞,建立一個 <code>不包含系統通知欄</code> 或 <code>透明系統通知欄</code> 的<code>前台服務</code>,提升App程序的系統優先級,使其不被系統清理。

Fork Native守護程序:

Android 5.0 以前,App内部 fork 出來的 <code>native程序</code> 不受系統管控。系統在殺死 App程序時,隻會殺死對應的<code>Java程序</code>。

是以誕生了一大批<code>流氓軟體</code>,通過<code>fork native程序</code>,在 App 的 Java 程序被殺死的時候,通過 ActivityManager 重新拉起被殺死的程序,進而達到<code>“程序永生”</code>的目的(這個方案據說最初由360提出,後來大家紛紛效仿)。

通過其他活躍App拉起:

程序保活的後期,又出現一種程序保活的方案。

多個App組成一個聯盟,隻要有一個App被使用者使用,其他所有聯盟内的App程序都會被拉起,以此來保證消息的及時到達。

例如:內建<code>個推、極光推送</code>的App,可以通過<code>前台活躍的App</code>拉起<code>不活躍的App程序</code>,提升所有內建<code>個推、極光推送</code>的第三方App推送消息的到達率。

注:

目前随着Android系統的不斷完善,以上方案大多不再有效。

Android系統源碼的開放,加之早期的系統尚不完善,衆多應用軟體提供商通過對AOSP各版本源碼的深入解讀,提出了各種<code>所謂黑科技的保活方案</code>,保證自己的應用程式程序不被系統清理。這段時期可謂是魑魅橫行、群魔亂舞;Android手機使用者則是苦不堪言,Android手機卡頓、待機時間短等問題也為人所诟病。

随着Android系統的不斷完善,Google和國内終端手機廠商也對Android系統做了很多的改進,如今已經基本封死了第三方應用各種所謂黑科技流氓保活方案。

Android背景程序限制;

國内手機廠商背景程序限制;

如今Google每年釋出的AOSP(Android Open Source Project)新版本中,每個版本均不斷<code>增加背景服務程序限制的相關條款</code>,一方面是為了限制第三方App背景服務程序的運作,節省使用者手機資源與電量消耗;另一方面,增加背景服務程序限制也是在保護使用者的隐私。

Android 5.0 開始,Android系統開始<code>以uid為辨別,清除APP程序組</code>,通過<code>殺死整個程序組</code>來殺死App程序,是以通過fork native 程序守護App程序這種方式從此不再有效。

一文讀懂Android程式及TCP動态心跳保活

Android 6.0開始,引入了<code>Doze模式</code>使用者拔下裝置的電源插頭,并在螢幕關閉後的一段時間後,裝置會進入<code>Doze模式</code>。

一文讀懂Android程式及TCP動态心跳保活

在Doze模式下,系統會嘗試通過限制應用通路網絡和 占用CPU資源的措施來節省電量,阻止應用通路網絡,并延遲作業與Alarm鬧鐘。

系統會定期退出Doze模式一小段時間,讓應用完成其延遲的活動。在此維護期内,系統會運作所有待處理的同步操作、Alarm鬧鐘,并允許應用通路網絡。

随着時間的推移,系統進入維護期的次數越來越少,這有助于在裝置未連接配接至充電器的情況下長期處于Doze模式狀态降低耗電量。

Android 7.0開始,<code>加強了Doze模式</code>,進入Doze模式不再要求裝置靜止狀态。

隻要螢幕關閉了一段時間,且裝置未插入電源,裝置就會進入Doze模。

一文讀懂Android程式及TCP動态心跳保活

Android 8.0開始,加強了應用背景執行限制:

不能再通過<code>startService</code>建立背景服務,否則将抛出異常;但可通過 <code>Context.startForegroundService()</code> 方法啟動一個帶通知欄提醒的前台服務;

應用處于背景時,會對背景應用檢索使用者目前位置資訊的頻率進行限制。應用每小時僅接收幾次位置資訊更新。

廣播限制:第三方應用将無法通過在<code>AndroidManifest</code>注冊靜态廣播來接收大部分的系統隐式廣播,以減少App對手機的喚醒,進而節省手機的電量;動态注冊不受影響。

Android 9.0開始,進一步加強了應用背景執行限制:

背景應用不再可以通路麥克風和攝像頭,傳感器(加速度傳感器、陀螺儀);

建立前台服務需要申請普通權限:<code>FOREGROUND_SERVICE</code>。

Android 10開始,再進一步加強了應用背景執行限制:

應用在背景運作時,通路手機位置需要動态申請<code>ACCESS_BACKGROUND_LOCATION</code>權限,使用者則可以選擇拒絕;

應用在背景運作時,對背景應用啟動Activity進行限制(運作前台服務的應用仍然會被應用看做“背景”應用)。

Android 11開始,再進一步完善了應用背景通路位置限制:

在Android11裝置上,對于targetSdkVersion=30(Android 11)的應用,需先申請前台位置權限,後申請背景位置權限。

在Android11裝置上,對于targetSdkVersion=30(Android 11)的應用,同時申請前台、背景位置權限時,系統會忽略該請求,無任何響應(需首先擷取前台位置權限,再次申請背景位置權限)。

在Android11裝置上,對于targetSdkVersion&lt;=29(Android 10)的應用,同時申請前台、背景位置權限時,對話框不再提示始終允許字樣,而是提供了位置權限的設定入口,需要使用者在設定頁面選擇始終允許才能獲得背景位置權限。

Google新釋出的各版本主要還是限制<code>第三方App背景程序服務的運作</code>,而國内各終端廠商則在AOSP的基礎上增加了<code>Alarm</code>的限制。

國内手機廠商(華米OV等)在手機系統休眠後,第三方App注冊的<code>Alarm定時喚醒鬧鐘幾乎全部無效!!!</code>

“Google的背景程序限制” 與 “國内手機廠商Alarm限制”相疊加的雙重影響是:

徹底封死了 “第三方手機軟體” 利用 “Alarm鬧鐘” 定時喚醒手機系統,維持 “終端” 與 “遠端伺服器” 之間的TCP長連接配接。達到 遠端伺服器 可随時拉起 終端App,提升APP使用者端使用時長(提升APP的DAU)這一方案。

國内手機廠商 Alarm 限制;

國内手機廠商 背景程序 限制;

國内終端手機廠商,不同廠商對應的Alarm限制方案也不相同,但目前已知的大概有以下兩個方向:

Alarm 對齊機制:

<code>當手機系統黑屏休眠時</code>,部分國内的手機品牌,會忽略 “第三方APP” 設定的 “Alarm喚醒周期”,強制将所有注冊Alarm鬧鐘的APP,<code>做Alarm喚醒周期對齊</code>。

例如:假設有三款App,其設定的Alarm喚醒周期分别為1分鐘、3分鐘、5分鐘。手機會直接忽略以上三款App的Alarm喚醒周期設定,強制将Alarm喚醒對齊為每5分鐘喚醒一次。

<code>系統休眠時,将所有App的喚醒時間做對齊,來減少手機的喚醒次數,節省使用者的待機電量消耗</code>。

Alarm 無效:

<code>當手機系統黑屏休眠時</code>,部分國内的手機品牌,忽略 “第三方APP” 注冊的全部Alarm,導緻第三方應用注冊的Alarm無效。

除了以上Alarm限制外,對于背景運作程序,不同終端廠商也進行了不同的限制。例如,部分終端廠商增加了背景程序耗電監測機制。

背景程序耗電監測機制:

<code>當手機系統黑屏休眠時</code>,部分國内的手機品牌,會啟動一個<code>耗電監測程序</code>,若發現某個背景程序持續耗電,将直接殺死耗電程序。

前邊說道第三方App程序若在背景運作,會受到國内廠商Alarm限制、背景耗電監測等限制。但也有例外情況,比如:<code>微信</code>。

這裡可以将其歸結為以下兩個白名單:

<code>Alarm 對齊白名單</code>:

<code>微信</code> 這個體量的App 會被直接添加到,國内手機廠商的<code>Alarm 對齊白名單</code>中。白名單中的程序,系統休眠時的<code>Alarm喚醒</code>将不再受到限制。

<code>系統守護程序白名單</code>:

若能達到微信的體量,國内手機廠商甚至可能會将其添加到 <code>系統守護程序白名單</code>。該白名單中的程序,若某些原因背景程序被殺,系統守護程序會在一定時間内迅速拉起該程序,進而保證程序的活躍。

前邊回顧了這幾年<code>在程序保活這個問題上</code>,<code>各軟體提供商</code>與<code>Android系統研發制造商</code>之間互相博弈過程。

如今在<code>“Google的背景程序限制” 與 “國内手機廠商Alarm限制”</code>雙重限制下,第三方軟體希望做到<code>App程序常駐背景</code>已經不太可能。

但每一個第三方App,基本都存在消息Push的需求。對于消息PUSH需求,第三方APP可使用的方案是什麼?

接入終端手機廠商 Push通道;

程序添加到廠商程序保活白名單;

在目前環境下的建議實作方案:接入終端手機廠商Push通道。

接入各終端廠商的Push通道,是最簡單的實作方案。

廠商的Push通道常駐記憶體,所有第三方App接入廠商Push後 <code>即能保證消息及時準确的到達,又可以減少終端使用者手機的常駐程序,延長使用者手機的待機時長</code>,可以說是對雙方都有利。

接入廠商PUSH 終端側實作方案;

接入廠商Push的 到達率上的注意點。

接入廠商PUSH 終端方案,終端側可通過建立與維護一個單獨的推送 <code>Module 子產品</code>,其中內建 <code>華為、小米、VIVO、OPPO、中興 5家</code>廠商的Push SDK;其他終端廠商的Push到達,可通過接入 <code>個推</code> 或 <code>極光推送</code>來實作。

<code>華米OV</code> 等頭部手機廠商:

通過接入<code>華米OV</code>等頭部廠商PUSH通道,保證市場上大多數手機使用者的PUSH到達率;

其他非頭部手機廠商:

通過<code>極光</code>或<code>個推</code>等第三方市場占有率較高的PUSH實作方案,來覆寫除 華米OV 等頭部手機廠商外的其他終端手機,保證市場上少部分手機使用者的PUSH到達率;

采用這個方案,研發人員需要開發和維護6個Push SDK組成的Module子產品。是以,接入廠商PUSH,優點和缺點可歸結如下。

優點:可以很好的保證 PUSH到達率;

缺點:開發與維護成本增加。

國内頭部手機終端廠商較多,研發的同學在一個App中需要同時維護 華為、小米、VIVO、OPPO、中興、魅族 等一系列廠商的PUSH SDK,研發維護成本急劇增加。

接入廠商Push的注意點;

将來終端手機廠商 PUSH管道 可能收費。

接入廠商Push的注意點

接入廠商PUSH,在PUSH到達上仍有不同的限制條件,這一點也<code>需要相關研發人員仔細研究各終端廠商PUSH的接入文檔</code>。

例如OPPO,存在一個<code>PUSH配額</code>問題:

OPPO PUSH配額是 OPPO推送消息的數量限制規則。每天的Push量 超過這個PUSH配額,OPPO将不再下發Push。

OPPO PUSH配額官方描述:

https://open.oppomobile.com/wiki/doc#id=10200

OPPO PUSH配額官方描述如下:

一文讀懂Android程式及TCP動态心跳保活

目前終端手機廠商的PUSH管道均是免費為開發者使用的,但随着全市場的PUSH通道均為各終端廠商把控後,第三方APP的消息PUSH也許存在收費的可能。個人認為廠商PUSH管道 <code>收費</code> 在不久的将來可能性還是很大的。

終端手機廠商追求的還是利益,是以隻要給錢或有錢賺,沒什麼不可談的。

與國内各終端廠商談合作 添加到對應的程序白名單中。

這個方案,需要與各終端廠商合作 達成利益上的同盟或找到利益契合點,進而使終端廠商為您的App開放程序保活白名單。

若 <code>您的公司與各終端廠商達成了利益同盟</code>,恭喜您可以考慮采用<code>維持一個終端與遠端伺服器的TCP長連接配接</code>,實作消息及時到達終端,提升使用者端App使用時長的PUSH方案了。

前邊提到,若<code>APP使用者體量足夠大</code> 或 <code>與各終端廠商達成了利益同盟</code>,可以考慮<code>維持一個終端與遠端伺服器的TCP長連接配接</code>,實作消息及時到達終端,提升使用者端App使用時長。

TCP心跳 相關标準;

維持 TCP心跳 不斷連;

TCP動态心跳 方案。

在Android下,通過自建 TCP長連接配接 來進行Push消息推送,TCP長連接配接若存活,消息Push才能及時送達。

而說到TCP心跳,那什麼是TCP心跳,TCP消息的結構又是什麼?

<code>rfc5626 4.4.1 Keep-Alive with CRLF</code>标準中,關于SIP消息的TCP心跳給出了标準。

Keep-Alive with CRLF;

CRLF 詳細說明;

ping pong 心跳消息。

<code>rfc5626 4.4.1 Keep-Alive with CRLF</code>中,SIP消息TCP心跳标準可以如下描述:

終端側需每隔一段時間(心跳間隔時間)需發送一個“ping”(double CRLF)消息,到遠端伺服器側;

終端發送“ping”消息後,若在10s之内未收到遠端服務端的“pong”(CRLF)消息,則終端認為與服務端的連接配接失敗。

一文讀懂Android程式及TCP動态心跳保活

根據<code>rfc5626 4.4.1 Keep-Alive with CRLF</code>标準:

終端上行的ping消息為 CRLFCRLF;

遠端伺服器下行的pong消息為 CRLF;

pong消息為<code>CRLF</code> ,含義是 <code>回車</code>+<code>換行</code> 符;

ping消息為<code>double CRLF</code>,也就是<code>CRLFCRLF</code> 含義是 <code>回車換行回車換行</code> 符。

CRLF 在ASCII表中與 16進制資料 的對應關系,如下圖所示:

一文讀懂Android程式及TCP動态心跳保活

ASCII的對應表中檢視:

ping心跳消息<code>CRLFCRLF</code>,對應的16進制資料為<code>0d0a0d0a</code>;

pong心跳消息<code>CRLF</code>,對應的16進制資料為<code>0d0a</code>;

心跳

含義

縮寫

十六進制

ping

終端上行心跳資料

CRLFCRLF

0d0a0d0a

pong

遠端伺服器下行心跳資料

CRLF

0d0a

這一節關于 ping pong心跳消息,從其消息發送接收流程、WireShark現網資料抓包、消息結構舉例 三方面進行介紹。

ping pong 心跳流程;

ping pong 心跳WireShark抓包;

ping pong 心跳消息舉例。

ping pong 心跳流程:

ping pong 心跳消息的發送/接收流程,如下圖所示:

一文讀懂Android程式及TCP動态心跳保活

終端側需每隔一段時間(心跳間隔時間)需發送一個“ping”(double CRLF 0xd0xa0xd0xa)消息,到遠端伺服器側;

終端發送“ping”消息後,若在10s之内未收到遠端服務端的“pong”(CRLF 0xd0xa)消息,則終端認為與服務端的連接配接失敗。

ping pong 心跳WireShark抓包:

ping pong 心跳WireShark抓包如下圖所示:

一文讀懂Android程式及TCP動态心跳保活

ping pong 心跳消息舉例:

ping pong 心跳消息的舉例如下所示:

TCP長連接配接的存活且有效,終端才能維持與遠端伺服器的TCP心跳,保證消息及時準确的到達。

是以影響TCP長連接配接穩定狀态的因素,值得研發人員重點關注:

營運商 NAT逾時;

終端 網絡狀态變化。

<code>NAT(Network Address Translation)</code> 是營運商的一個位址轉換網關。生活中最常見的NAT裝置,是我們家中使用的<code>路由器</code>。

國内運作商網絡下,因為 IP v4 的 IP 數量有限,營運商配置設定給手機終端的 IP 是營運商内網的 IP,手機要連接配接 Internet,需要通過營運商的網關做一個網絡位址轉換(Network Address Translation,NAT)。

一文讀懂Android程式及TCP動态心跳保活

簡單的說營運商的網關需要維護一個外網 IP、端口到内網 IP、端口的對應關系,以確定内網的手機可以跟 Internet 的伺服器通訊。

内網位址

外網位址

192.168.0.3:8888

120.132.92.21:9202

192.168.0.2:5566

120.132.92.21:9200

如上表所示:

NAT裝置會根據NAT表對 發送 和 接收 的資料做修改, 比如将<code>192.168.0.3:8888</code>發出去的資料封包改成<code>120.132.92.21:9202</code>,外部就認為他們是在和<code>120.132.92.21:9202</code>通信。

NAT裝置會将<code>120.132.92.21:9202</code>收到的封包資料 IP和端口改成<code>192.168.0.3:8888</code> 再發給内網的主機,這樣内部和外部就能互相通信了。

但如果<code>192.168.0.3:8888 == 120.132.92.21:9202</code>這一映射因為某些原因被NAT裝置淘汰了,那麼外部裝置就無法與<code>192.168.0.3:8888</code>通信了。

為了節省資源,大部分國内移動網絡營運商 在鍊路一段時間沒有資料通訊時,會淘汰 NAT 表中的對應項,造成通信雙方鍊路的中斷。

是以,為了應對營運商NAT逾時,<code>終端</code>需<code>每隔一段時間</code>向 <code>遠端伺服器</code> 發送一個 <code>TCP保活消息</code>,也就是<code>TCP保活心跳</code>。

以上也就是為什麼終端與遠端伺服器,需要維持TCP心跳的原因。

終端網絡狀态變化,也會使TCP長連接配接斷連,比如:終端移動網絡與WIFI網絡切換、網絡斷開與重新連 等

是以,終端 APP 需監聽相應網絡狀态變化事件:<code>若發現終端網絡狀态發生變化,需重建立立TCP長連接配接</code>。

跟随手機狀态變化 調整心跳狀态;

TCP 動态心跳周期的計算;

備援心跳。

這裡我們可以将手機不同狀态劃進行劃分,比如:

應用處于前台時為活躍态,剛剛進入背景或息屏時為次活躍态,應用進入背景一段時間後為背景狀态,手機斷網或關機後為IDEL狀态。

可根據使用者手機不同狀态變化,動态調整應用的TCP心跳周期。

若應用處于前台活躍态:固定心跳。

當應用處于前台活躍狀态時,為了保證消息及時準确的達到,使用固定心跳,保證使用者體驗。

應用剛進入背景(或息屏)的次活躍态:使用幾次固定心跳。

應用進入背景(或息屏)時,先用幾次固定跳維持長連結,保證使用者剛剛息屏或應用剛剛進入背景,消息的及時與準确到達,然後進入背景自适應心跳計算。

應用進入背景(或息屏)一段時間後:使用動态心跳。

應用進入背景(或息屏)一段時間後,采用動态心跳,減少因心跳引起的空中信道資源消耗,以及因心跳引起的終端喚醒與電量消耗。

使用者切換網絡或重新聯網:重建立立TCP長連接配接。

使用者斷網後,直接進入IDEL狀态,此時需檢測使用者網絡狀态變化,若使用者聯網後,則重建TCP長連接配接;

使用者切換網絡狀态(WIFI、移動網絡互相切換),也需要重建立立TCP連接配接;

應用重新進入前台活躍态:固定心跳。

應用重新進入前台活躍狀态,重新采用固定心跳,保證使用者消息及時準确到達。

一文讀懂Android程式及TCP動态心跳保活

注:應用進入背景(或者息屏)時,先用幾次最小心跳維持長連結,然後采用動态心跳。這樣做的目的是 盡量選擇使用者不活躍的時間段,來減少因動态心跳可能産生的 消息送達不及時,進而對使用者體驗産生影響。

動态計算心跳前,假設預定義定義幾個資料常量:

MinHeart 最小心跳間隔時間;

MaxHeart 最大心跳間隔時間;

HeartStep 心跳增加時間步長;

預定義幾個資料變量:

successHeart 動态探測 穩定後的心跳間隔時間;

curHeart 目前成功心跳 初始為MinHeart;

MinHeart、MaxHeart、HeartStep為預先定義的固定資料常量。

successHeart、curHeart為我們要探測的資料變量。

一文讀懂Android程式及TCP動态心跳保活

如上圖所示:

應用進入背景(或者息屏)時,先用最小心跳間隔 MinHeart 維持心跳長連結;

若連續三次MinHeart心跳均成功,則認為下一次相同時間間隔的心跳大機率也會成功;此時下次心跳,可以嘗試增加一次心跳步進HeartStep;

增加TCP心跳步進後,再次進行三次心跳探測,若連續三次均成功,則繼續增加HeartStep步進,向上探測;

若出現失敗,則同一個curHeart累計出現3次失敗時,則認為這個時間為NAT逾時時間;

同一個 curHeart 需要累計3次失敗,才認定為失敗,是為了排除使用者處于弱網環境的情況下,比如地鐵快速行進中。

同一個 curHeart 累計3次失敗時,則認為找到了NAT逾時時間。

下次心跳使用 successHeart = curHeart- HeartStep 作為心跳時間周期。

使用 successHeart 作為心跳周期,若連續成功,則一直使用 successHeart 作為心跳周期;

使用 successHeart 作為心跳周期,若連續出現3次失敗,則認為探測資料失敗,或者使用者更換了網絡環境,需重新探測。

在使用者對手機的的一些主動操作時,需增加備援心跳,確定及時收到消息。

當使用者點亮螢幕(或熄滅螢幕)時,立刻做一次心跳;

當應用切換到前台(或切換到背景)時,立刻做一次心跳;

當使用者切換網絡狀态時,重建立立TCP長連接配接;

1像素Activity程序保活:

https://blog.csdn.net/zhenufo/article/details/79317068

Optimize for Doze and App Standby:

https://developer.android.google.cn/training/monitoring-device-state/doze-standby

Android 7.0 行為變更:

https://developer.android.google.cn/about/versions/nougat/android-7.0?hl=zh-cn

Android 8.0 行為變更:

https://developer.android.google.cn/about/versions/oreo/android-8.0-changes?hl=zh-cn

Android 9.0 行為變更:

https://developer.android.google.cn/about/versions/pie/android-9.0-changes-28?hl=zh-cn

Android10 行為變更:

https://developer.android.google.cn/about/versions/10/privacy?hl=zh-cn

Android11 行為變更:

https://developer.android.google.cn/about/versions/11/behavior-changes-all?hl=zh-cn

IPV6部署之後 是否還會大量使用NAT?

https://www.zhihu.com/question/27316663

Using Native IPv6 via Comcast in San Francisco:

https://blog.kylemanna.com/ipv6/using-native-ipv6-via-comcast-in-san-francisco/

rfc5626 SIP TCP心跳:

https://datatracker.ietf.org/doc/html/rfc5626#section-4.4.1

TCP Keep-Alive 和 應用層探活:

https://www.jianshu.com/p/00aec37b6be8

WebSocket細節 長連接配接保活及其原理:

https://baijiahao.baidu.com/s?id=1661934194124740212&amp;wfr=spider&amp;for=pc

2020年Android最新保活實作原理揭秘:

https://cloud.tencent.com/developer/news/585273

Andoird TCP通訊:

https://www.cnblogs.com/duwenqidu/p/12361811.html

關于TCP長連接配接、NAT逾時、心跳包

https://www.cnblogs.com/sjjg/p/5830009.html

Android微信智能心跳方案:

https://mp.weixin.qq.com/s/ghnmC8709DvnhieQhkLJpA

一文讀懂Android程式及TCP動态心跳保活