中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

招聘網(wǎng)站建設(shè)人員的要求搜索優(yōu)化

招聘網(wǎng)站建設(shè)人員的要求,搜索優(yōu)化,大連 商城網(wǎng)站制作公司,北京網(wǎng)站設(shè)計(jì)的公司價(jià)格系列文章目錄 提示:這里可以添加系列文章的所有文章的目錄,目錄需要自己手動(dòng)添加 例如:第一章 Python 機(jī)器學(xué)習(xí)入門之pandas的使用 文章目錄 系列文章目錄前言ANR流程概覽ANR觸發(fā)機(jī)制一、service超時(shí)機(jī)制二、broadcast超時(shí)機(jī)制三、provider超…

系列文章目錄

提示:這里可以添加系列文章的所有文章的目錄,目錄需要自己手動(dòng)添加
例如:第一章 Python 機(jī)器學(xué)習(xí)入門之pandas的使用


文章目錄

  • 系列文章目錄
  • 前言
  • ANR流程概覽
  • ANR觸發(fā)機(jī)制
  • 一、service超時(shí)機(jī)制
  • 二、broadcast超時(shí)機(jī)制
  • 三、provider超時(shí)機(jī)制
  • 四、input超時(shí)機(jī)制
  • ANR信息收集
  • Question


前言

不論從事安卓應(yīng)用開發(fā),還是安卓系統(tǒng)研發(fā),應(yīng)該都遇到應(yīng)用無響應(yīng)(ANR,Application Not Responding)問題,當(dāng)應(yīng)用程序一段時(shí)間無法及時(shí)響應(yīng),則會(huì)彈出ANR對(duì)話框,讓用戶選擇繼續(xù)等待,還是強(qiáng)制關(guān)閉。

那么哪些場景會(huì)造成ANR呢?
Service Timeout:比如前臺(tái)服務(wù)在20s內(nèi)未執(zhí)行完成;
BroadcastQueue Timeout:比如前臺(tái)廣播在10s內(nèi)未執(zhí)行完成
ContentProvider Timeout:內(nèi)容提供者,在publish過超時(shí)10s;
InputDispatching Timeout: 輸入事件分發(fā)超時(shí)5s,包括按鍵和觸摸事件。

ANR流程概覽

我們通過一張流程圖來了解整個(gè)ANR的流程:
在這里插入圖片描述
無論是哪種類型的ANR,哪怕是native層的ANR,最終也會(huì)通知到AnrHelper類的appNotResponding方法。所以,我們從這個(gè)方法開始了解整個(gè)ANR的流程。我們用來區(qū)分ANR的四種不同類型,其實(shí)也就是appNotResponding這個(gè)方法中的annotation不同而已,而ANR本身是不去分類型的。

  1. appNotResponding方法中,主要是生成AnrRecord對(duì)象,加入到mAnrRecords集合中。然后調(diào)用startAnrConsumerIfNeeded方法。
  2. startAnrConsumerIfNeeded方法主要是通過cas進(jìn)行判斷,避免兩個(gè)ANR線程同時(shí)執(zhí)行。如果沒有沖突的話,則開啟AnrConsumerThread線程,對(duì)mAnrRecords中的對(duì)象進(jìn)行消費(fèi)。
  3. AnrConsumerThread的run方法中,就是從mAnrRecords中取出對(duì)象,這些對(duì)象第一條中添加的。通過AnrRecord自身的appNotResponding方法進(jìn)行消費(fèi)。
  4. appNotResponding方法就是整個(gè)ANR流程的核心執(zhí)行邏輯了??偨Y(jié)一下,其實(shí)主要分為兩大塊:
    • 生成ANR的相關(guān)log以及日志并打印或保存
    • 觸發(fā)ANR超時(shí)機(jī)制,彈出應(yīng)用無響應(yīng)的框

ANR日志生成可查看ANR原理篇 - ANR信息收集過程
下面篇章,主要看下ANR觸發(fā)機(jī)制。

ANR觸發(fā)機(jī)制

ANR是一套監(jiān)控Android應(yīng)用響應(yīng)是否及時(shí)的機(jī)制,可以把發(fā)生ANR比作是引爆炸彈,整個(gè)流程包含三部分組成:
1.埋定時(shí)炸彈:中控系統(tǒng)(system_server進(jìn)程)啟動(dòng)倒計(jì)時(shí),在規(guī)定時(shí)間內(nèi)如果目標(biāo)(應(yīng)用進(jìn)程)沒有干完所有的活,則中控系統(tǒng)會(huì)定向炸毀(殺進(jìn)程)目標(biāo)。
2.拆炸彈:在規(guī)定的時(shí)間內(nèi)干完工地的所有活,并及時(shí)向中控系統(tǒng)報(bào)告完成,請(qǐng)求解除定時(shí)炸彈,則幸免于難。
3.引爆炸彈:中控系統(tǒng)立即封裝現(xiàn)場,抓取快照,搜集目標(biāo)執(zhí)行慢的罪證(traces),便于后續(xù)的案件偵破(調(diào)試分析),最后是炸毀目標(biāo)。
常見的ANR有service、broadcast、provider以及input。
更多細(xì)節(jié)詳見下面兩篇:
ANR原理篇 - service/broadcast/provider超時(shí)機(jī)制
ANR原理篇 - Input超時(shí)機(jī)制

一、service超時(shí)機(jī)制

下面來看看埋炸彈與拆炸彈在整個(gè)服務(wù)啟動(dòng)(startService)過程所處的環(huán)節(jié):
在這里插入圖片描述
圖解:

  1. 客戶端(App進(jìn)程)向中控系統(tǒng)(system_server進(jìn)程)發(fā)起啟動(dòng)服務(wù)的請(qǐng)求
  2. 中控系統(tǒng)派出一名空閑的通信員(binder_1線程)接收該請(qǐng)求,緊接著向組件管家(ActivityManager線程)發(fā)送消息,埋下定時(shí)炸彈
  3. 通訊員1號(hào)(binder_1)通知工地(service所在進(jìn)程)的通信員準(zhǔn)備開始干活
  4. 通訊員3號(hào)(binder_3)收到任務(wù)后轉(zhuǎn)交給包工頭(main主線程),加入包工頭的任務(wù)隊(duì)列(MessageQueue)
  5. 包工頭經(jīng)過一番努力干完活(完成service啟動(dòng)的生命周期),然后等待SharedPreferences(簡稱SP)的持久化;
  6. 包工頭在SP執(zhí)行完成后,立刻向中控系統(tǒng)匯報(bào)工作已完成
  7. 中控系統(tǒng)的通訊員2號(hào)(binder_2)收到包工頭的完工匯報(bào)后,立刻拆除炸彈。如果在炸彈倒計(jì)時(shí)結(jié)束前拆除炸彈則相安無事,否則會(huì)引發(fā)爆炸(觸發(fā)ANR)

更多細(xì)節(jié)詳見startService啟動(dòng)過程分析。

二、broadcast超時(shí)機(jī)制

broadcast跟service超時(shí)機(jī)制大抵相同,如下圖所示。
在這里插入圖片描述
圖解:

  1. 客戶端(App進(jìn)程)向中控系統(tǒng)(system_server進(jìn)程)發(fā)起發(fā)送廣播的請(qǐng)求
  2. 中控系統(tǒng)派出一名空閑的通信員(binder_1)接收該請(qǐng)求轉(zhuǎn)交給組件管家(ActivityManager線程)
  3. 組件管家執(zhí)行任務(wù)(processNextBroadcast方法)的過程埋下定時(shí)炸彈
  4. 組件管家通知工地(receiver所在進(jìn)程)的通信員準(zhǔn)備開始干活
  5. 通訊員3號(hào)(binder_3)收到任務(wù)后轉(zhuǎn)交給包工頭(main主線程),加入包工頭的任務(wù)隊(duì)列(MessageQueue)
  6. 包工頭經(jīng)過一番努力干完活(完成receiver啟動(dòng)的生命周期),然后等待SP工人完成SP數(shù)據(jù)的持久化工作,便可以向中控系統(tǒng)匯報(bào)工作完成
  7. 中控系統(tǒng)的通訊員2號(hào)(binder_2)收到包工頭的完工匯報(bào)后,立刻拆除炸彈。如果在倒計(jì)時(shí)結(jié)束前拆除炸彈則相安無事,否則會(huì)引發(fā)爆炸(觸發(fā)ANR)

對(duì)于靜態(tài)注冊的廣播在超時(shí)檢測過程,還多一個(gè)步驟:需要檢測SP,位于第6步和第7步之間。
SP的apply將修改的數(shù)據(jù)項(xiàng)更新到內(nèi)存,然后再異步同步數(shù)據(jù)到磁盤文件,因此很多地方會(huì)推薦在主線程調(diào)用采用apply方式,避免阻塞主線程,但靜態(tài)廣播超時(shí)檢測過程需要SP全部持久化到磁盤,如果過度使用apply會(huì)增大應(yīng)用ANR的概率,更多細(xì)節(jié)詳見系統(tǒng)SharedPreferences工作過程。

Google這樣設(shè)計(jì)的初衷是針對(duì)靜態(tài)廣播的場景下,保障進(jìn)程被殺之前一定能完成SP的數(shù)據(jù)持久化。因?yàn)樵谙蛑锌叵到y(tǒng)匯報(bào)廣播接收者工作執(zhí)行完成前,該進(jìn)程的優(yōu)先級(jí)為Foreground級(jí)別,高優(yōu)先級(jí)下進(jìn)程不但不會(huì)被殺,而且能分配到更多的CPU時(shí)間片,加速完成SP持久化。更多細(xì)節(jié)詳見Android Broadcast廣播機(jī)制。

三、provider超時(shí)機(jī)制

provider的超時(shí)是在provider進(jìn)程首次啟動(dòng)的時(shí)候才會(huì)檢測,當(dāng)provider進(jìn)程已啟動(dòng)的場景,再次請(qǐng)求provider并不會(huì)觸發(fā)provider超時(shí)。
在這里插入圖片描述
圖解:

  1. 客戶端(App進(jìn)程)向中控系統(tǒng)(system_server進(jìn)程)發(fā)起獲取內(nèi)容提供者的請(qǐng)求
  2. 中控系統(tǒng)派出一名空閑的通信員(binder_1)接收該請(qǐng)求,檢測到內(nèi)容提供者尚未啟動(dòng),則先通過zygote孵化新進(jìn)程
  3. 新孵化的provider進(jìn)程向中控系統(tǒng)注冊自己的存在
  4. 中控系統(tǒng)的通信員2號(hào)接收到該信息后,向組件管家(ActivityManager線程)發(fā)送消息,埋下炸彈
  5. 通信員2號(hào)通知工地(provider進(jìn)程)的通信員準(zhǔn)備開始干活
  6. 通訊員4號(hào)(binder_4)收到任務(wù)后轉(zhuǎn)交給包工頭(main主線程),加入包工頭的任務(wù)隊(duì)列(MessageQueue)
  7. 包工頭經(jīng)過一番努力干完活(完成provider的安裝工作)后向中控系統(tǒng)匯報(bào)工作已完成
  8. 中控系統(tǒng)的通訊員3號(hào)(binder_3)收到包工頭的完工匯報(bào)后,立刻拆除炸彈。如果在倒計(jì)時(shí)結(jié)束前拆除炸彈則相安無事,否則會(huì)引發(fā)爆炸(觸發(fā)ANR)

更多細(xì)節(jié)詳見理解ContentProvider原理。

四、input超時(shí)機(jī)制

input的超時(shí)檢測機(jī)制跟service、broadcast、provider截然不同,
為了更好的理解input過程先來介紹兩個(gè)重要線程的相關(guān)工作:

  • InputReader線程負(fù)責(zé)通過EventHub(監(jiān)聽目錄/dev/input)讀取輸入事件,一旦監(jiān)聽到輸入事件則放入到InputDispatcher的mInBoundQueue隊(duì)列,并通知其處理該事件;
  • InputDispatcher線程負(fù)責(zé)將接收到的輸入事件分發(fā)給目標(biāo)應(yīng)用窗口,分發(fā)過程使用到3個(gè)事件隊(duì)列:
    • mInBoundQueue用于記錄InputReader發(fā)送過來的輸入事件;
    • outBoundQueue用于記錄即將分發(fā)給目標(biāo)應(yīng)用窗口的輸入事件;
    • waitQueue用于記錄已分發(fā)給目標(biāo)應(yīng)用,且應(yīng)用尚未處理完成的輸入事件;

input的超時(shí)機(jī)制并非時(shí)間到了一定就會(huì)爆炸,而是處理后續(xù)上報(bào)事件的過程才會(huì)去檢測是否該爆炸,所以更像是掃雷的過程,具體如下圖所示:
在這里插入圖片描述

圖解:

  1. InputReader線程通過EventHub監(jiān)聽底層上報(bào)的輸入事件,一旦收到輸入事件則將其放至mInBoundQueue隊(duì)列,并喚醒InputDispatcher線程
  2. InputDispatcher開始分發(fā)輸入事件,設(shè)置埋雷的起點(diǎn)時(shí)間。先檢測是否有正在處理的事件(mPendingEvent),如果沒有則取出mInBoundQueue隊(duì)頭的事件,并將其賦值給mPendingEvent,且重置ANR的timeout;否則不會(huì)從mInBoundQueue中取出事件,也不會(huì)重置timeout。然后檢查窗口是否就緒(checkWindowReadyForMoreInputLocked),滿足以下任一情況,則會(huì)進(jìn)入掃雷狀態(tài)(檢測前一個(gè)正在處理的事件是否超時(shí)),終止本輪事件分發(fā),否則繼續(xù)執(zhí)行步驟3。
    • 對(duì)于按鍵類型的輸入事件,則outboundQueue或者waitQueue不為空,
    • 對(duì)于非按鍵的輸入事件,則waitQueue不為空,且等待隊(duì)頭時(shí)間超時(shí)500ms
  3. 當(dāng)應(yīng)用窗口準(zhǔn)備就緒,則將mPendingEvent轉(zhuǎn)移到outBoundQueue隊(duì)列
  4. 當(dāng)outBoundQueue不為空,且應(yīng)用管道對(duì)端連接狀態(tài)正常,則將數(shù)據(jù)從outboundQueue中取出事件,放入waitQueue隊(duì)列
  5. InputDispatcher通過socket告知目標(biāo)應(yīng)用所在進(jìn)程可以準(zhǔn)備開始干活
  6. App在初始化時(shí)默認(rèn)已創(chuàng)建跟中控系統(tǒng)雙向通信的socketpair,此時(shí)App的包工頭(main線程)收到輸入事件后,會(huì)層層轉(zhuǎn)發(fā)到目標(biāo)窗口來處理
  7. 包工頭完成工作后,會(huì)通過socket向中控系統(tǒng)匯報(bào)工作完成,則中控系統(tǒng)會(huì)將該事件從waitQueue隊(duì)列中移除。

input超時(shí)機(jī)制為什么是掃雷,而非定時(shí)爆炸呢?
是由于對(duì)于input來說即便某次事件執(zhí)行時(shí)間超過timeout時(shí)長,只要用戶后續(xù)在沒有再生成輸入事件,則不會(huì)觸發(fā)ANR。 這里的掃雷是指當(dāng)前輸入系統(tǒng)中正在處理著某個(gè)耗時(shí)事件的前提下,后續(xù)的每一次input事件都會(huì)檢測前一個(gè)正在處理的事件是否超時(shí)(進(jìn)入掃雷狀態(tài)),檢測當(dāng)前的時(shí)間距離上次輸入事件分發(fā)時(shí)間點(diǎn)是否超過timeout時(shí)長。如果完成前一個(gè)輸入事件,則會(huì)重置ANR的timeout,從而不會(huì)爆炸。

ANR信息收集

對(duì)于service、broadcast、provider、input發(fā)生ANR后,中控系統(tǒng)會(huì)馬上去抓取現(xiàn)場的信息,用于調(diào)試分析。收集的信息包括如下:

  1. 將am_anr信息輸出到EventLog,也就是說ANR觸發(fā)的時(shí)間點(diǎn)最接近的就是EventLog中輸出的am_anr信息
  2. 收集以下重要進(jìn)程的各個(gè)線程調(diào)用棧trace信息,保存在data/anr/traces.txt文件
    • 當(dāng)前發(fā)生ANR的進(jìn)程,system_server進(jìn)程以及所有persistent進(jìn)程
    • audioserver, cameraserver, mediaserver, surfaceflinger等重要的native進(jìn)程
    • CPU使用率排名前5的進(jìn)程
  3. 將發(fā)生ANR的reason以及CPU使用情況信息輸出到main log
  4. 將traces文件和CPU使用情況信息保存到dropbox,即data/system/dropbox目錄
  5. 對(duì)用戶可感知的進(jìn)程則彈出ANR對(duì)話框告知用戶,對(duì)用戶不可感知的進(jìn)程發(fā)生ANR則直接殺掉

整個(gè)ANR信息收集過程比較耗時(shí),其中抓取進(jìn)程的trace信息,每抓取一個(gè)等待200ms,可見persistent越多,等待時(shí)間越長。

關(guān)于抓取trace命令,對(duì)于Java進(jìn)程可通過在adb shell環(huán)境下執(zhí)行kill -3 [pid]可抓取相應(yīng)pid的調(diào)用棧;
對(duì)于Native進(jìn)程在adb shell環(huán)境下執(zhí)行debuggerd -b [pid]可抓取相應(yīng)pid的調(diào)用棧。
對(duì)于ANR問題發(fā)生后的蛛絲馬跡(trace)在traces.txt和dropbox目錄中保存記錄。
更多細(xì)節(jié)詳見理解Android ANR的信息收集過程

有了現(xiàn)場信息,可以調(diào)試分析,先定位發(fā)生ANR時(shí)間點(diǎn),然后查看trace信息,接著分析是否有耗時(shí)的message、binder調(diào)用,鎖的競爭,CPU資源的搶占,以及結(jié)合具體場景的上下文來分析,調(diào)試手段就需要針對(duì)前面說到的message、binder、鎖等資源從系統(tǒng)角度細(xì)化更多debug信息,這里不再展開,后續(xù)再以ANR案例來講解。

作為應(yīng)用開發(fā)者應(yīng)讓主線程盡量只做UI相關(guān)的操作,避免耗時(shí)操作,比如過度復(fù)雜的UI繪制,網(wǎng)絡(luò)操作,文件IO操作;避免主線程跟工作線程發(fā)生鎖的競爭,減少系統(tǒng)耗時(shí)binder的調(diào)用,謹(jǐn)慎使用sharePreference,注意主線程執(zhí)行provider query操作。簡而言之,盡可能減少主線程的負(fù)載,讓其空閑待命,以期可隨時(shí)響應(yīng)用戶的操作。

Question

有哪些路徑會(huì)引發(fā)ANR?
答案是從埋下定時(shí)炸彈到拆炸彈之間的任何一個(gè)或多個(gè)路徑執(zhí)行慢都會(huì)導(dǎo)致ANR(以service為例),可以是service的生命周期的回調(diào)方法(比如onStartCommand)執(zhí)行慢,可以是主線程的消息隊(duì)列存在其他耗時(shí)消息讓service回調(diào)方法遲遲得不到執(zhí)行,可以是SP操作執(zhí)行慢,可以是system_server進(jìn)程的binder線程繁忙而導(dǎo)致沒有及時(shí)收到拆炸彈的指令。另外ActivityManager線程也可能阻塞,出現(xiàn)的現(xiàn)象就是前臺(tái)服務(wù)執(zhí)行時(shí)間有可能超過10s,但并不會(huì)出現(xiàn)ANR。

發(fā)生ANR時(shí)從trace來看主線程卻處于空閑狀態(tài)或者停留在非耗時(shí)代碼的原因有哪些?
可以是抓取trace過于耗時(shí)而錯(cuò)過現(xiàn)場,可以是主線程消息隊(duì)列堆積大量消息而最后抓取快照一刻只是瞬時(shí)狀態(tài),可以是廣播的“queued-work-looper”一直在處理SP操作。


致謝:
理解Android ANR的觸發(fā)原理
http://gityuan.com/2016/07/02/android-anr/
ANR信息收集過程
http://gityuan.com/2016/12/02/app-not-response/
Intpu原理分析
http://gityuan.com/2017/01/01/input-anr/
徹底理解安卓應(yīng)用無響應(yīng)機(jī)制
http://gityuan.com/2019/04/06/android-anr/
ANR顯示和日志生成原理講解

http://www.risenshineclean.com/news/29051.html

相關(guān)文章:

  • springmvc是做網(wǎng)站的嗎seo站長網(wǎng)怎么下載
  • 臨沂做網(wǎng)站的杭州小程序建設(shè)公司
  • wordpress下載代碼刷關(guān)鍵詞排名seo軟件軟件
  • 做 在線觀看免費(fèi)網(wǎng)站網(wǎng)站投放廣告費(fèi)用
  • 網(wǎng)站 linux 服務(wù)器配置百度關(guān)鍵詞優(yōu)化曝光行者seo
  • 做雞蛋期貨看什么網(wǎng)站重慶關(guān)鍵詞排名首頁
  • linux 一鍵 WordPress網(wǎng)站免費(fèi)優(yōu)化軟件
  • 做一款推薦類的網(wǎng)站google搜索首頁
  • 網(wǎng)站制作加我百度客服電話號(hào)碼
  • 威海專業(yè)做網(wǎng)站設(shè)計(jì)的公司怎么在百度上推廣自己的產(chǎn)品
  • 什么瀏覽器可以進(jìn)黃頁zol問答沈陽seo按天計(jì)費(fèi)
  • 注冊微信小程序流程直通車優(yōu)化推廣
  • 做推廣哪個(gè)平臺(tái)網(wǎng)站好百度網(wǎng)站收錄提交入口全攻略
  • 長春網(wǎng)站建設(shè)聯(lián)系吉網(wǎng)傳媒優(yōu)愛站關(guān)鍵詞挖掘old
  • 沈陽市網(wǎng)站建設(shè)報(bào)價(jià)凡科建站網(wǎng)站
  • 做單頁網(wǎng)站怎么選產(chǎn)品免費(fèi)seo網(wǎng)站
  • 網(wǎng)站排名優(yōu)化機(jī)構(gòu)汕頭網(wǎng)站建設(shè)開發(fā)
  • 做視頻網(wǎng)站需要什么資質(zhì)廈門seo百度快照優(yōu)化
  • 哈爾濱建設(shè)網(wǎng)站哪家好市場推廣專員
  • joomla 網(wǎng)站建設(shè)教程不受國內(nèi)限制的搜索引擎
  • 大連企業(yè)網(wǎng)站排名東莞網(wǎng)絡(luò)推廣及優(yōu)化
  • 做網(wǎng)站網(wǎng)站建設(shè)教程滄州網(wǎng)站建設(shè)優(yōu)化公司
  • 網(wǎng)站標(biāo)題字體設(shè)計(jì)湖南企業(yè)seo優(yōu)化首選
  • 企業(yè)域名申請(qǐng)流程百度seo優(yōu)化推廣公司
  • 社交網(wǎng)絡(luò)推廣方法有哪些寧波seo外包快速推廣
  • 南通網(wǎng)站建設(shè)公司排名適合企業(yè)員工培訓(xùn)的課程
  • 上海十大網(wǎng)站建設(shè)西安seo服務(wù)
  • 學(xué)校網(wǎng)站的目的發(fā)布廣告的平臺(tái)免費(fèi)
  • 如何將網(wǎng)站做的更美觀seo技術(shù)代理
  • 淘寶做促銷的網(wǎng)站個(gè)人如何推廣app