今天代碼寫着寫着就莫名閃退了,手機也沒有「程序中止運行」的提示,logcat也沒有看到藍色的調用棧log,這樣的閃退最是蛋疼了,還好必現。復現幾回以後,終於從logcat中看到了一行可疑的log: A/Looper: Could not create epoll instance. errno=24
,看起來又是在native層閃退了。本文就把這個問題的分析解決過程記錄了下來。java
碰見沒填過的坑,第一反應就是Google之,果真前幾個結果中一個 Stack Overflow的問答 就爲這個問題的解決提供了很好的思路。固然搜索結果並不能直接解決問題,若是Google的結果直接就能解決問題,我也就不必寫這樣一篇文章,徒增無用信息了。git
除了可以直接搜到徹底同樣的問題,而且已經有了解決辦法的狀況,還有時候只能搜到相關的問題,可是沒有解決辦法,或者解決辦法不work,或者壓根兒搜不到相關信息,這時候就須要本身根據已有信息一步步分析了,甚至只能本身一步步趟坑了,一般有幾種情形:github
有log,可是搜索結果沒有解決方案(常常遇到有人兩年前在stack overflow上問了一個如出一轍的問題,可是沒有答案),或者解決方案不work。這時咱們能夠 根據搜到的信息,肯定問題出在哪兒 。就好比這個問題, stack overflow上的回答 就說多是打開了太多文件,而採納的回答說去掉 looper.prepare()
就解決了問題,那就多是建立了太多的 lopper
。又好比以前一篇文章中遇到的log A/libc: Fatal signal 11 (SIGSEGV) at 0x00000010 (code=1), thread 9302 (RxComputationTh)
,搜索結果就說多是對native代碼的多線程執行致使的。多線程
有log,可是搜索不到有意義的結果。有時候搜索無結果多是由於搜索內容包含了太多本地計算機相關的信息,好比文件路徑,不少時候 刪掉文件路徑、時間戳等信息,就能搜到結果了 。若是仍是搜不到結果,而log又有較明確的意義,這時候咱們就能夠 直接分析log的含義,肯定問題的緣由 。好比以前另外一篇文章中遇到的 error: 不兼容的類型: java.util.List<java.lang.Object>沒法轉換爲 java.util.List<com.github.piasy.model.entities.GithubUser>
,拿着這個錯誤信息去搜確定都是不相干的結果,由於去掉本身定義的類路徑以後,過短並且太常見了(類型轉換錯誤)。可是經過分析報錯信息,能夠知道確實是類型轉換錯誤。經過在代碼中找和這個類相關的發生了類型轉換的地方,最終解決了問題。oop
最慘的狀況就是沒有log,或者log沒有任何有用信息了。這時候若是問題是忽然冒出來的,這時候就能夠經過 代碼差別分析 來肯定引入bug的代碼了,一般狀況下二分查找是最高效的,而git則有一個無比牛逼的命令, git bisect
,經過二分查找commit,來定位引入bug的壞commit。而若是隻有一個commit,或者沒有版本控制(啥?),那就只能新拉一個分支,經過逐步註釋/刪除代碼,來定位bug代碼了。測試
好吧上面不是最慘的,最慘的就是上面的狀況都沒法適用。這就真的沒別的辦法了,只能推倒重來了,其實這仍是屬於經過回滾來定位壞代碼的類型,因而可知,回滾是定位bug的萬精油,只不過效率多是最低的。線程
A/Looper: Could not create epoll instance. errno=24
錯誤的分析解決過程好了回到本次的具體問題上來,既然判斷多是因爲建立了太多的looper致使的閃退,那就查看代碼咯。可是個人代碼並無一處建立了looper呀!別急,looper還有個兄弟handler,handler但是常用的,看看是否是handler建立了太多。版本控制
經過爲建立handler的代碼加「非中斷」斷點(調試時不中斷程序執行,只記錄log),發現確實就是建立了太多的handler!調試
好了,找到了問題可能的緣由,改掉會致使建立過多handler的代碼,測試運行,閃退確實再也不出現了,OK問題圓滿解決 :)code