1. 程式人生 > >Activity在後臺被回收,這個時候觸發showDialog,窗體洩露,WindowManager.BadTokenException

Activity在後臺被回收,這個時候觸發showDialog,窗體洩露,WindowManager.BadTokenException

今天在友盟上看到一個崩潰日誌,如下:

android.view.WindowManager$BadTokenException: Unable to add window -- token [email protected] is not valid; is your activity running?
	at android.view.ViewRootImpl.setView(ViewRootImpl.java:798)
	at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:288)
	at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:73)
	at android.app.Dialog.show(Dialog.java:287)
	at com.module.exam.ExamActivity$1.onTimeCountFinished(ExamActivity.java:71)
	at com.module.question.QuestionBaseActivity$5.onTimeCountFinished(QuestionBaseActivity.java:324)
	at com.utils.TimeCount.onFinish(TimeCount.java:49)
	at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:118)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:137)
	at android.app.ActivityThread.main(ActivityThread.java:5493)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:525)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
	at dalvik.system.NativeStart.main(Native Method)
問題原因在於,我的ExamActivity是一個擁有CountDownTimer元件來執行倒計時業務的物件,該物件原始碼實現可以看到是通過訊息佇列機制,sendMessageDelay(msg,time)來實現的,所以就有一種情況,考試ExamActivity 在後臺執行,這個時候Timer還在執行倒計時,一段時間後,考試ExamActivity被系統回收掉了,倒計時還在執行,當倒計時完成後觸發 onTimerFinish()方法, 這個時候如果dialog.show() 就會報該錯誤。是因為這個時候window與Activity分離了,造成了窗體洩露。

解決方法:  

                      1.  判斷當前Activity是否finish()了通過  isFinishing()

                      2.  在show時,捕獲異常

示例程式碼如下

setTimeCountListener(new TimeCount.OnTimeCountListener() {
            @Override
            public void onTimeCountFinished() {
                if(!ExamActivity.this.isFinishing()){
                    final TipsDialog tipsDialog = new TipsDialog(ExamActivity.this);
                    tipsDialog.oneBtn("答題時間已到,本次考試結束,請交卷", "交卷", new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            tipsDialog.dismiss();
                            endExam();
                        }
                    });
                    try {
                        tipsDialog.show();
                    }catch (WindowManager.BadTokenException e){
                        LogUtil.e(e.toString());
                    }
                }
            }

這樣就保證了不會發生類似錯誤了。

總結:

         當程式中有類似 postMessageDelay 這種控制dialog顯示的情況時,一定要考慮到Activity被回收這種情況。另外看Activity原始碼  onDestory裡判斷所有還在執行的dialog都會被主動銷燬。這是另外一個問題。

相關推薦

Activity後臺回收這個時候觸發showDialog窗體洩露WindowManager.BadTokenException

今天在友盟上看到一個崩潰日誌,如下: android.view.WindowManager$BadTokenException: Unable to add window -- token [email protected] is not valid; is y

【挖坑埋你】我違反了保密協議正在通緝我覺得我很快就會抓走,這個祕密我不得不說了其實人類已經在2012年12月25日世界末日滅絕的差不多了僅存了一批科學家和不到一百個倖存者開啟了拯救毀滅計劃用了五年

挖坑埋你 我違反了保密協議,正在被通緝,我覺得我很快就會被抓走,這個祕密我不得不說了,其實人類已經在2012年12月25日世界末日滅絕的差不多了,僅存了一批科學家和不到一百個倖存者,開啟了拯救毀滅計劃,用了五年...

寫了6年程式碼30歲程式設計師要去做外包這個選擇靠譜麼.網友別!

做了6年程式設計師,30歲程式設計師要去做外包,這個選擇靠譜麼.網友,別! 在網際網路行業,作為一名技術人員,大部分人都有換工作的經歷,不過在職業生涯內,換工作的次數也是非常有限的(個人覺得超過2位數就算是比較頻繁了),每一次換工作,都算是人生的重大選擇,都有可能決定今後的命運。因此作出這

spring cloud 入門(六)【容錯機制二(通過方法容錯)這個方法是面向介面程式設計我覺得更好一些】

程式碼結構如下:   pom 檔案中新增  hystrix <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>

BigDecimal的round模式 轉載其他博主 我備忘這個不是我寫的寫的很好

    BigDecimal round_down round_half_up等 mark round mode: - BigDecimal.ROUND_DOWN 截端操作,類似truncate 該模式永遠不會增加被操作的數的值  

震驚這個大資料技術全球獨此一家怎麼學習大資料?

小白如何學習大資料技術?大資料怎麼入門?怎麼做大資料分析?資料科學需要學習那些技術?大資料的應用前景等等問題,已成為熱門大資料領域熱門問題,以下是對新手如何學習大資料技術問題的解答~ 大資料開發學習可以按照以下內容進行學習   網際網路科技發展蓬勃興起,人工智慧時代來臨,抓住下

震驚這個大資料技術全球獨此一家究竟是何原因。

在目前相信大多數IT開發人員對於人工智慧+大資料並不陌生,使用的場景也越來越廣,日常開發中前端同學也逐漸接觸了更多與大資料相關的開發需求。因此對大資料知識也有必要進行一些學習理解,帶大家來學習瞭解一下大資料的基礎知識。 大資料的本質 一、資料的儲存:分散式檔案系統(分散式儲存) 二、資料

Vue增加對象屬性觸發視圖變化問題刪除對象屬性方法

size 問題 lock 發生 方法 info set -s http   在vue中,直接將data內的某個對象賦值為空,對象改變了,但是視圖不會發生變化,這個時候,可以用set進行對象屬性的設置,同時引發視圖的變化:     vue組件內想刪除對象的屬性,有

activity回收點選Tab無法切換fragment

1、原因:當activity在後臺並且記憶體不足時,系統會把activity給回收掉,但也會儲存部分(不是全部)資訊用於下次頁面恢復。這樣會導致下次進入頁面後佈局或資料錯亂,並且點選底部Tab無法切換fragment。 2、解決方法: (1)方法一:註釋掉sup

APP在後臺系統回收如何重新啟動

問題: app執行在後臺,android系統會在記憶體不夠用的時候,回收app,如果app中有全域性的變數,那麼再次開啟app可能會出現崩潰的情況。 示例: 示例原始碼 public class MyApplication extends App

關於fragmentactivity回收之後重新恢復

當記憶體不足的時候位於後臺的應用會被系統回收掉,只是保留著任務棧,再次進入的時候會恢復它們。 要注意的地方有:系統只會把ui相關的東西存起來和恢復,其他的一些成員變數都不會管。 會把生命週期和建立一樣重新走一遍,這個時候得注意那些不是從onCreat這樣的生命週期方法中獲得

activity回收fragment恢復處理

例如activity放在後臺一段時間,當activity被回收之後,再重新進入activity的時候,會重新呼叫onCreate(),並且savedInstanceState不再是null,因此可以判斷出是否被回收。 onCreate中不要重複建立fragment,通過

在一個Activity中結束另一個Activity的方法;如何是從A跳轉到B 結束A的;關於Activity後臺銷燬的處理;關於Activity後臺銷燬的處理

型別一:在一個Activity中結束另一個Activity的方法 下面的以ActivityB 結束ActivityA 為例: 方法一: 1.首先在 ActivityA 中定義一個 Activity

程式後臺Activity回收後再次啟動fragment失效問題

/////////////////2016/07/01///////////////////// /////////////////by  xbw////////////////////////// /////////////////環境  eclipse///////////////// 先上個圖,

小心了這個設置會導致你的vm重啟時強制重裝系統!

含義 start 就是 rom 如果 翻譯 volatile root hat 主標題:小心了,這個設置會導致你的vm重啟時被強制重裝系統! 副標題:關於計算方案中"可變"的含義 初次使用者容易犯的錯誤,誤認為該選項是此處設置的各項參數,在日後使用過程中可以調整。其實不是

DEDE 網站後臺黑鏈修改了自己登入不上去怎麼辦?

開啟dede_admin資料表: 進入你的MYSQL後臺,然後在你的資料庫名中,找到dede_admin這項如圖,pwd下的值就是你的密碼,織夢密碼採取的是MD5加密,破解麻煩而且沒有必要,重置簡單最

Activity回收掉之後的網路請求回撥處理方法詳解

想起寫這麼一篇博文的前提是上週去面試了一家公司,其中有這麼一個問題印象深刻,結合當時在網上看到的解決辦法我就說了一個錯誤答案,結果當場就被面試官給指出了錯誤,所以回來後和我的領導一起討論了這麼一個問題,他提出了一個很好地解決思路,於是乎我便寫了這麼一段程式

Activity回收導致繫結Fragment呼叫getActivity()拋空指標異常

當系統記憶體不足,Fragment的宿主Activity被回收的時候,Fragment的例項並沒有隨之被回收。Activity被系統回收時,會主動呼叫onSaveInstance()方法來儲存檢視層(

Activity回收掉之後的網路回撥處理

早上來到公司剛開啟電腦,就被叫到會議室,召開緊急會議,線上出現重大bug,根據線上日誌統計,崩潰率上升了0.3個百分點(我們專案是集成了騰訊Bugly統計日誌,有興趣的同學可以去了解下)。 這個可不得了,聽說領導被老闆叫過去訓了好久,領導憋了一肚子火,我們的日

java垃圾回收機制中什麼物件會回收掉?

從GC-root搜尋不到,而且經過第一次標記,清理後,仍然沒有復活的物件。http://www.importnew.com/21492.htmlhttps://www.cnblogs.com/xiaoxi/p/6486852.html