Android TimeoutException閃退記錄及解決

此問題在oppo R9 系列的手機(jī)出現(xiàn)較多,而且主要集中在Android 5.1-6.0的手機(jī)系統(tǒng)。
TimeoutException,在Android 系統(tǒng)里會出現(xiàn)下面這些吴旋,在釋放資源時,因耗時導(dǎo)致的寒亥,可能不是10s,可能會是20s,30s邮府,60s,120s荧关。具體跟手機(jī)有關(guān)溉奕。

android.database.CursorWindow.finalize() timed out after 10 seconds

java.util.regex.Matcher.finalize() timed out after 10 seconds

android.graphics.Bitmap$BitmapFinalizer.finalize() timed out after 10 seconds

org.apache.http.impl.conn.SingleClientConnManager.finalize() timed out after 10 seconds

java.util.concurrent.ThreadPoolExecutor.finalize() timed out after 10 seconds

android.os.BinderProxy.finalize() timed out after 10 seconds

android.graphics.Path.finalize() timed out after 10 seconds

這些都 會導(dǎo)致此閃退出現(xiàn)。這個bug,在stackoverflow數(shù)量還是比較 多的忍啤。
經(jīng)過google查詢加勤,最終在
具體的分析及解決可以詳細(xì)閱讀滴滴移動團(tuán)隊(duì) 分享的文章
https://mp.weixin.qq.com/s/uFcFYO2GtWWiblotem2bGg

我按滴滴的文章,還是會閃退同波,對于 app的異常監(jiān)聽鳄梅,可參考之前的一篇文章 http://www.reibang.com/p/2cb297395bd4

由于我們App還集成了一些第三方 的SDK,這個SDK 里都有實(shí)現(xiàn)對 異常 的攔截處理未檩,如jpush戴尸、umeng、神策打點(diǎn)冤狡。所以當(dāng)我在自己的
Thread.UncaughtExceptionHandler孙蒙,處理完后项棠,會再拋出一個java.lang.RuntimeException,最終還是會走異常的處理邏輯挎峦,造成App閃退香追。

1 xxxxx.CrashHandler.uncaughtException()
2 com.umeng.analytics.pro.j.uncaughtException()
3 com.qiyukf.unicorn.j.d$1.uncaughtException()
4 cn.jiguang.a.a.c.e.uncaughtException()
5 com.tencent.bugly.crashreport.crash.e.b()
6 com.tencent.bugly.crashreport.crash.e.uncaughtException()
7 java.lang.Daemons$FinalizerWatchdogDaemon.finalizerTimedOut(Daemons.java:316)
8 java.lang.Daemons$FinalizerWatchdogDaemon.run(Daemons.java:238)
9 java.lang.Thread.run(Thread.java:833)
2019-07-23 11:24:31.277 11406-11419/xxxx E/[ FinalizerWatchdogDaemon:CrashHandler:uncaughtException():62 ]: ==thread==FinalizerWatchdogDaemon
2019-07-23 11:24:31.278 11406-11419/xxxx E/[ FinalizerWatchdogDaemon:CrashHandler:uncaughtException():67 ]: ===ex=java.util.concurrent.TimeoutException: xxxx.ui.index.FinlaizeTimeoutObject.finalize() timed out after 60 seconds
2019-07-23 11:24:31.278 11406-11419/xxxx E/[ FinalizerWatchdogDaemon:CrashHandler:uncaughtException():70 ]: ===ignore=
2019-07-23 11:24:31.280 11406-11419/xxxx E/AndroidRuntime: FATAL EXCEPTION: FinalizerWatchdogDaemon
    Process: xxxx, PID: 11406
    java.lang.RuntimeException: java.util.concurrent.TimeoutException: xxxx.ui.index.FinlaizeTimeoutObject.finalize() timed out after 60 seconds
        at cn.jiguang.a.a.c.e.uncaughtException(Unknown Source:69)
        at com.xiaomi.mipush.sdk.z.uncaughtException(Unknown Source:25)
        at com.loc.ai.uncaughtException(Unknown Source:21)
        at com.loc.ay.uncaughtException(Unknown Source:232)
        at java.lang.Daemons$FinalizerWatchdogDaemon.finalizerTimedOut(Daemons.java:424)
        at java.lang.Daemons$FinalizerWatchdogDaemon.runInternal(Daemons.java:285)
        at java.lang.Daemons$Daemon.run(Daemons.java:105)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: java.util.concurrent.TimeoutException: xxxx.ui.index.FinlaizeTimeoutObject.finalize() timed out after 60 seconds
        at java.lang.Thread.sleep(Native Method)
        at java.lang.Thread.sleep(Thread.java:373)
        at java.lang.Thread.sleep(Thread.java:314)
        at xxxx.ui.index.FinlaizeTimeoutObject.finalize(FinlaizeTimeoutObject.java:11)
        at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:252)
        at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:239)
        at java.lang.Daemons$Daemon.run(Daemons.java:105) 
        at java.lang.Thread.run(Thread.java:764) 
2019-07-23 11:24:34.356 11406-11419/xxxx E/[ FinalizerWatchdogDaemon:CrashHandler:uncaughtException():62 ]: ==thread==FinalizerWatchdogDaemon
2019-07-23 11:24:34.356 11406-11419/xxxx E/[ FinalizerWatchdogDaemon:CrashHandler:uncaughtException():67 ]: ===ex=java.lang.RuntimeException: java.util.concurrent.TimeoutException: xxxx.ui.index.FinlaizeTimeoutObject.finalize() timed out after 60 seconds
2019-07-23 11:24:34.356 11406-11419/xxxx E/[ FinalizerWatchdogDaemon:CrashHandler:uncaughtException():72 ]: ===ex=java.lang.RuntimeException: java.util.concurrent.TimeoutException: xxxx.ui.index.FinlaizeTimeoutObject.finalize() timed out after 60 seconds
2019-07-23 11:24:34.358 11406-11419/xxxx E/CrashReport: CrashReport has not been initialed! pls to call method 'initCrashReport' first!
2019-07-23 11:24:37.359 11406-11419/xxxx E/Tinker.TinkerUncaughtExceptionHandler: uncaughtException:java.util.concurrent.TimeoutException: xxxx.ui.index.FinlaizeTimeoutObject.finalize() timed out after 60 seconds
2019-07-23 11:24:37.359 11406-11419/xxxx W/Tinker.TinkerUncaughtExceptionHandler: tinker is not loaded
2019-07-23 11:24:37.361 11406-11419/xxxx E/Tinker.UncaughtHandler: TinkerUncaughtHandler catch exception:java.lang.RuntimeException: java.util.concurrent.TimeoutException: xxxx.ui.index.FinlaizeTimeoutObject.finalize() timed out after 60 seconds
        at cn.jiguang.a.a.c.e.uncaughtException(Unknown Source:69)
        at com.xiaomi.mipush.sdk.z.uncaughtException(Unknown Source:25)
        at com.loc.ai.uncaughtException(Unknown Source:21)
        at com.loc.ay.uncaughtException(Unknown Source:232)
        at java.lang.Daemons$FinalizerWatchdogDaemon.finalizerTimedOut(Daemons.java:424)
        at java.lang.Daemons$FinalizerWatchdogDaemon.runInternal(Daemons.java:285)
        at java.lang.Daemons$Daemon.run(Daemons.java:105)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: java.util.concurrent.TimeoutException: xxxx.ui.index.FinlaizeTimeoutObject.finalize() timed out after 60 seconds
        at java.lang.Thread.sleep(Native Method)
        at java.lang.Thread.sleep(Thread.java:373)
        at java.lang.Thread.sleep(Thread.java:314)
        at xxxx.ui.index.FinlaizeTimeoutObject.finalize(FinlaizeTimeoutObject.java:11)
        at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:252)
        at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:239)
        at java.lang.Daemons$Daemon.run(Daemons.java:105) 
        at java.lang.Thread.run(Thread.java:764) 

如何設(shè)計(jì)出一個TimeoutException。
先自己隨便寫一下類坦胶,暫且叫透典,CustomTimeoutException吧。重寫finalize()方法顿苇,在里面將線程sleep 100s峭咒,這個是測試出來的,上文有提到纪岁,不同的手機(jī) 讹语、系統(tǒng)對應(yīng)超時時間不一樣,我用了一個魅族 5.1的手機(jī) 蜂科,20s,在小米 note 2 8.0 系統(tǒng) 是60s.

public class CustomTimeoutException {
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("====開始Timeout處理====");
        // 每個手機(jī)觸發(fā) Timeout 的時長不同顽决,看情況修改
        Thread.sleep(100*1000);
        System.out.println("====結(jié)束Timeout處理====");
    }
}

然后在一個頁面加一個點(diǎn)擊事件,throwsTimeout()

private void throwsTimeout(){
        new Thread(()->{
            new CustomTimeoutException();
            Runtime.getRuntime().gc();
            System.runFinalization();
        }).start();
    }

點(diǎn)擊按鈕后导匣,我們會看到打印 :
\color{red}{====開始Timeout處理====}
但遲遲不見:\color{red}{====結(jié)束Timeout處理====} 日志.
注意才菠,我在測試時,并不是每次出現(xiàn)贡定,有時會打印“====結(jié)束Timeout處理====” 日志赋访,猜測可能跟我 開啟一下線程處理這個有關(guān),因?yàn)槲也]有阻塞 UI線程缓待,App還是可以 繼續(xù)使用蚓耽。
為什么要開啟一個線程,不然很容易造成ANR(10s),無法復(fù)現(xiàn)此問題旋炒。

經(jīng)過這個步悠,我最終并沒有完全按滴滴提供的方法處理此異常。只要檢測到是線程名是 FinalizerWatchdogDaemon,我就忽略此異常瘫镇,這樣鼎兽,這樣也就不會被其它的 異常處理 類強(qiáng)制 退出App。

/**
     * 當(dāng)UncaughtException發(fā)生時會轉(zhuǎn)入該函數(shù)來處理
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        System.out.println("==thread=="+thread.getName());
        System.out.println("===ex="+ex);
        System.out.println("===isTimeOut="+(ex instanceof TimeoutException)); 
        System.out.println("=isThread=="+
               TextUtils.equals(thread.getName(),
                       "FinalizerWatchdogDaemon"));
        if(TextUtils.equals(thread.getName(),
                  "FinalizerWatchdogDaemon")) {
            //&&ex instanceof TimeoutException)
            System.out.println("===ignore=");
        }else {
           // 正常處理異常铣除,該上拋的上拋谚咬,該交給系統(tǒng) 處理的交給系統(tǒng)處理。
        }

雖然問題是解決了尚粘,但這并沒有從根本上解決這個問題择卦,真的要減少此異常的話,還是得規(guī)范開發(fā)的,盡量讓App減少 GC的回收秉继。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末潘明,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子秕噪,更是在濱河造成了極大的恐慌钳降,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腌巾,死亡現(xiàn)場離奇詭異遂填,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)澈蝙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門吓坚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人灯荧,你說我怎么就攤上這事礁击。” “怎么了逗载?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵哆窿,是天一觀的道長。 經(jīng)常有香客問我厉斟,道長挚躯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任擦秽,我火速辦了婚禮码荔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘感挥。我一直安慰自己缩搅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上乙帮,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機(jī)與錄音熔恢,去河邊找鬼轻姿。 笑死,一個胖子當(dāng)著我的面吹牛袱蜡,可吹牛的內(nèi)容都是我干的丝蹭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼坪蚁,長吁一口氣:“原來是場噩夢啊……” “哼奔穿!你這毒婦竟也來了镜沽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤贱田,失蹤者是張志新(化名)和其女友劉穎缅茉,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體男摧,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蔬墩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了耗拓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拇颅。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖乔询,靈堂內(nèi)的尸體忽然破棺而出樟插,到底是詐尸還是另有隱情,我是刑警寧澤竿刁,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布黄锤,位于F島的核電站,受9級特大地震影響食拜,放射性物質(zhì)發(fā)生泄漏猜扮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一监婶、第九天 我趴在偏房一處隱蔽的房頂上張望旅赢。 院中可真熱鬧,春花似錦惑惶、人聲如沸煮盼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽僵控。三九已至,卻和暖如春鱼冀,著一層夾襖步出監(jiān)牢的瞬間报破,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工千绪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留充易,地道東北人。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓荸型,卻偏偏與公主長得像盹靴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355