本系列博文 基於是前微信高階工程師張紹文專欄 《Android開發高手課》的讀書筆記。
文章所寫內容是本人讀完的感悟,需要原文的朋友請自行購買。
Android的開發前景如何
移動網際網路發展不知不覺已經十多年過去了,“風口上的豬”也從Mobile First變成了AI First.
作為從業者的我們能很清楚的感受到移動端的招聘量變少了,但不得不提的是中高階崗位需求卻更多了.
這說明移動網際網路已經過了高速發展的階段,逐漸成熟規範了。對從業者的要求也變高了,面對這種情況,
我們能做的就是不斷提高自己的技術深度,同時也得擴寬技術廣度.
至於一些跨平臺技術,如RN,PWA,Weex,以及Flutter雖然能代替一部分App開發的需求,但在最終的實現效果
上還是比不上原生開發。所以移動端的從業人員不要急著去改換門庭,應該花更多的時間去修煉內功.
另外移動端開發也不僅限於App開發,還有loT(物聯網),音視訊,VR/AR 等這些領域也是離不開移動網際網路的.
崩潰優化
我們通常所說的崩潰就是指程式出現異常.Android下的崩潰分為java崩潰和Native崩潰。
其中java崩潰還算是比較好找的,網上也有挺多日誌上報的方法.
而Native崩潰呢.一般都是因為在 Native 程式碼中訪問非法地址,也可能是地址對齊出現了問題,或者發生了程式主動 abort,這些都會產生相應的 signal 訊號,導致程式異常退出。
Android開發高手課中講的多是Native崩潰的處理,然而我個人對這部分內容瞭解的也很少,所以下文多是摘取張老師專利中的重點內容。
Native入門可先看這篇博文 Android 平臺 Native 程式碼的崩潰捕獲機制及實現
Native 崩潰從捕獲到解析一般要經歷以下流程
- 編譯端。編譯 C/C++ 程式碼時,需要將帶符號資訊的檔案保留下來。
- 客戶端。捕獲到崩潰時候,儘可能地將有用的資訊寫入日誌,然後選擇適當的時間傳到伺服器
- 服務端 . 讀取日誌,尋找合適的符號檔案,生成可讀的C/C++呼叫棧.
第三方工具中比較成熟的當屬Chromium的Breakpad
在異常捕獲過程中最重要的是保證在各種極端情況下生成崩潰日誌,同時要保證程式不發生二次崩潰。
生成日誌時會出現的問題
-
檔案控制程式碼洩漏,導致建立日誌檔案失敗,怎麼辦?
我們需要提前申請檔案控制程式碼 fd 預留,防止出現這種情況。
-
因為棧溢位了,導致日誌生成失敗,怎麼辦?
為了防止棧溢位導致程式沒有空間建立呼叫棧執行處理函式,我們通常會使用常見的 signalstack。
在一些特殊情況,我們可能還需要直接替換當前棧,所以這裡也需要在堆中預留部分空間。
-
整個堆的記憶體都耗盡了,導致日誌生成失敗,怎麼辦?
這個時候我們無法安全地分配記憶體,也不敢使用 stl 或者 libc 的函式,因為它們內部實現會分配堆記憶體
這個時候如果繼續分配記憶體,會導致出現堆破壞或者二次崩潰的情況.Breakpad 做的比較徹底,重新封裝了Linux Syscall Support,來避免直接呼叫 libc。
-
堆破壞或二次崩潰導致日誌生成失敗,怎麼辦?
Breakpad 會從原程式 fork 出子程式去收集崩潰現場,此外涉及與 Java 相關的,一般也會用子程式去操作。
這樣即使出現二次崩潰,只是這部分的資訊丟失,我們的父程式後面還可以繼續獲取其他的資訊。
在一些特殊的情況,我們還可能需要從子程式 fork 出孫程式。
當然對於一般的公司來說,要做這些還是有些強人所難,幸運的是市面上有合適的服務.比如騰訊的Bugly,阿里的啄木鳥平臺,網易雲捕等.
在熱修復流行的當下,就算線上傳送了一些崩潰,也可能通過打補丁來達到線上修復。但是如果崩潰發生在啟動的時,在熱修復程式碼執行之前,那就糟糕了。所以一些大公司的產品還會有"安全模式"來保障啟動流程.
安全模式
在App熱修復中有一個特殊情況,就是應用在啟動階段crash,根本啟動不了,熱修復就難以奏效。這個時候可以採取一種安全模式的啟動方式.
簡單來說,就是增加一個flag啟動標記位,用來標記使用者是否連續兩次啟動失敗,這個時候就會進入安全模式進入修改階段.修復的方式
- 自修復,清空業務資料,嘗試啟動
- 熱修復,根據配置檔案來判斷是否修改
- 重製為初始安裝狀態,將Document、Library、Cache三個根目錄清空
詳細可看 安全模式:天貓App啟動保護實踐
如何快速定位崩潰
發生崩潰就一定會有崩潰資訊,那麼我們應該看的是那部分資訊?
1.崩潰基本資訊
程式名、執行緒名。崩潰的程式是前臺程式還是後臺程式,崩潰是不是發生在 UI 執行緒。
崩潰的堆疊和型別.是java崩潰,Native崩潰,還是ANR.是自己的程式碼問題,還是系統的程式碼問題.
2.系統和應用的執行日誌.
系統的event logcat會記錄App執行的一些基本情況,記錄在/system/etc/event-log-tags 中。
system logcat:
10-25 17:13:47.788 21430 21430 D dalvikvm: Trying to load lib ...
event logcat:
10-25 17:13:47.788 21430 21430 I am_on_resume_called: 生命週期
10-25 17:13:47.788 21430 21430 I am_low_memory: 系統記憶體不足
10-25 17:13:47.788 21430 21430 I am_destroy_activity: 銷燬 Activty
10-25 17:13:47.888 21430 21430 I am_anr: ANR 以及原因
10-25 17:13:47.888 21430 21430 I am_kill: APP 被殺以及原因
複製程式碼
3.機型、系統、廠商、CPU、ABI、Linux 版本等
上述這些資料可用作橫向比較,你經常會發現某個問題只會在特定的情況下出現。
4.裝置狀態 是否root,是否是模擬器.有些問題是由Xposed 或多開軟體造成
5.記憶體資訊,考慮一些記憶體不足的崩潰是否多發生在低記憶體的手機上.
6.自定義的應用資訊
這部分資訊主要用來輔助定位崩潰位置.可以記錄崩潰發生的位置,某個activity;還可以記錄發生崩潰之前的幾個操作步驟,便於復現崩潰場景.
解決崩潰
1.優先順序: 優先解決Top 崩潰或者對業務有重大影響;其次簡單易排查的java崩潰,疑難雜症放到最後
2.嘗試復現: 針對疑難雜症,可以通過早先在日誌中自定義的應用資訊來複現崩潰過程
3.著眼硬體: 排查是否是手機系統,記憶體,機型引起的。
4.系統錯誤: 有些問題是Android系統不同版本之間存在的問題。
最後,給自己公眾號打個廣告,【碼農的嘮叨】聊技術,聊熱文,聊網際網路趣事,也發嘮叨