1. 程式人生 > >ProgressDialog的hide()和dismiss()方法

ProgressDialog的hide()和dismiss()方法

在使用ProgressDialog作為網路載入資料的請求過程中,當資料載入完成,筆者很自然的將ProgressDialog呼叫了hide()方法,在當前activity退出時,遇到問題了android.view.WindowLeaked: Activity com.xxx.xxx.hangup.ProgressDialogActivity has leaked window com.android.internal.policy.PhoneWindow$DecorView{dd0bacf G.E...... R.....I. 0,0-684,0} that was originally added here


這個問題是說當前dialog所依附的activity被銷燬,dialog依然存在,未被銷燬。這真是平時使用api時,沒怎麼注意的結果呀。呼叫hide()方法是可以實現dialog的隱藏,但是dialog物件並未銷燬。
下面是一個簡單的測試這種異常程式碼

public class ProgressDialogActivity extends Activity {
    private ProgressDialog pd;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super
.onCreate(savedInstanceState); //建立一個ProgressDialog,並執行show()方法 pd = new ProgressDialog(this); pd.setMessage("在activity中showdialog後,直接退出activity異常"); pd.setTitle("dialog異常測試"); pd.show(); } @Override protected void onResume() { super.onResume(); //暫時在onResume()中掉了dialog的hide()方法,然後我們執行手機back鍵,會發現異常log
/** * 01-01 02:37:26.845: E/MultiWindowProxy(25617): getServiceInstance failed! 01-01 02:37:30.569: E/WindowManager(25617): android.view.WindowLeaked: Activity com.xxx.xxx.hangup.ProgressDialogActivity has leaked window com.android.internal.policy.PhoneWindow$DecorView{dd0bacf G.E...... R.....I. 0,0-684,0} that was originally added here 01-01 02:37:30.569: E/WindowManager(25617): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:460) 01-01 02:37:30.569: E/WindowManager(25617): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:306) 01-01 02:37:30.569: E/WindowManager(25617): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85) 01-01 02:37:30.569: E/WindowManager(25617): at android.app.Dialog.show(Dialog.java:326) 01-01 02:37:30.569: E/WindowManager(25617): at com.xxx.xxxx.hangup.ProgressDialogActivity.onCreate(ProgressDialogActivity.java:25) 01-01 02:37:30.569: E/WindowManager(25617): at android.app.Activity.performCreate(Activity.java:6301) 01-01 02:37:30.569: E/WindowManager(25617): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113) 01-01 02:37:30.569: E/WindowManager(25617): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2523) 01-01 02:37:30.569: E/WindowManager(25617): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2658) 01-01 02:37:30.569: E/WindowManager(25617): at android.app.ActivityThread.-wrap11(ActivityThread.java) 01-01 02:37:30.569: E/WindowManager(25617): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1492) 01-01 02:37:30.569: E/WindowManager(25617): at android.os.Handler.dispatchMessage(Handler.java:111) 01-01 02:37:30.569: E/WindowManager(25617): at android.os.Looper.loop(Looper.java:207) 01-01 02:37:30.569: E/WindowManager(25617): at android.app.ActivityThread.main(ActivityThread.java:5741) 01-01 02:37:30.569: E/WindowManager(25617): at java.lang.reflect.Method.invoke(Native Method) 01-01 02:37:30.569: E/WindowManager(25617): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795) 01-01 02:37:30.569: E/WindowManager(25617): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:685) */ if(pd != null){ pd.hide(); } } }

上面註釋是異常log資訊。

下面看下hide()和dismiss()方法的具體實現:
hide()原始碼實現如下:
/**
* Hide the dialog, but do not dismiss it.
*/
public void hide() {
if (mDecor != null) {
mDecor.setVisibility(View.GONE);
}
}

很明確的看到dialog是一個view檢視,而hide()實現中只是將view設定為gone,並未移除。
dialog的dismiss()方法如下:

 /**
     * Dismiss this dialog, removing it from the screen. This method can be
     * invoked safely from any thread.  Note that you should not override this
     * method to do cleanup when the dialog is dismissed, instead implement
     * that in {@link #onStop}.
     */
    @Override
    public void dismiss() {
        if (Looper.myLooper() == mHandler.getLooper()) {
            dismissDialog();
        } else {
            mHandler.post(mDismissAction);
        }
    }

在看下dismissDialog內的實現:

 void dismissDialog() {
        if (mDecor == null || !mShowing) {
            return;
        }

        if (mWindow.isDestroyed()) {
            Log.e(TAG, "Tried to dismissDialog() but the Dialog's window was already destroyed!");
            return;
        }

        try {
            mWindowManager.removeViewImmediate(mDecor);
        } finally {
            if (mActionMode != null) {
                mActionMode.finish();
            }
            mDecor = null;
            mWindow.closeAllPanels();
            onStop();
            mShowing = false;

            sendDismissMessage();
        }
    }

看到了mWindowManager.removeViewImmediate(mDecor)的程式碼。
至此,dialog的view才被真正移除。
希望小夥伴們不要犯和我一樣的low的錯誤。。。

相關推薦

ProgressDialog的hide()dismiss()方法

在使用ProgressDialog作為網路載入資料的請求過程中,當資料載入完成,筆者很自然的將ProgressDialog呼叫了hide()方法,在當前activity退出時,遇到問題了android.view.WindowLeaked: Activity co

Dialog 的cancel dismiss 方法

然後在Dialog類中找到了dismiss和cancel方法的實現。重要看dismiss的原始碼: Java程式碼 public void cancel() {         if (mCancelMessage != null) {                          // Obtain a

Activiy或者Fragment 銷燬時,Dialog 的正確Dismiss方式測試方法

場景:Activity或者Fragment 中彈出一個 Dialog,幾秒後會 dismiss。平時測試沒遇到崩潰,但是崩潰平臺卻捕捉到如下錯誤java.lang.IllegalArgumentExc

(轉)Android 開發 對話方塊Dialog dismisshide方法的區別

原地址:https://www.pocketdigi.com/20120815/900.html dismiss和hide方法都可以隱藏對話方塊,在需要的時候也可以用show方法呼叫顯示。但是,這兩者是有區別的。 dismiss方法會釋放對話方塊所佔的資源,而hide

web測試中的測試點測試方法總結

動態 小數 圖片尺寸 提示信息 方便 margin style 容錯性 字符型 測試是一種思維,包括情感思維和智力思維,情感思維主要體現在一句俗語:思想決定行動上(要懷疑一切),智力思維主要體現在測試用例的設計上。具有了這樣的思想,就會找出更多的bug。 一、輸入框

函數中的私有變量特權方法

getc 單例 隱藏數據 需要 接口 返回對象 div 外部 his 定義   【1】【私有變量】  任何在函數中定義的變量,都可以認為是私有變量,因為不能在函數外部訪問這些變量。私有變量包括函數的參數、局部變量和在函數內部定義的其他函數   【2】【特權方法】  如果在函

[C#學習筆記之異步編程模式2]BeginInvokeEndInvoke方法 (轉載)

cti otf 函數返回 編程模式 catch 數值 gin 單線程 blog 為什麽要進行異步回調?眾所周知,普通方法運行,是單線程的,如果中途有大型操作(如:讀取大文件,大批量操作數據庫,網絡傳輸等),都會導致方法阻塞,表現在界面上就是,程序卡或者死掉,界面元素不動了,

jquery中prop()方法attr()方法的區別淺析

clas ttr over dex idt pro query selected accesskey jquery1.6中新加了一個方法prop(),一直沒用過它,官方解釋只有一句話:獲取在匹配的元素集中的第一個元素的屬性值。 大家都知道有的瀏覽器只要寫disabled,c

scroll()scrollTop()方法——實現電商網站中的電梯導航

窗口 css樣式 ram 每一個 最新 top index hid none 要想實現電商網站的電梯導航效果,首先需要了解以下知識點: jquery 事件 - scroll() 方法 對元素滾動的次數進行計數,當用戶滾動指定的元素時,會發生 scroll 事件。scroll

【設計模式】簡單工廠模式工廠方法模式

產生 for plm nbsp osc rbm play stp mage > 簡單工廠模式 顧名思義,此模式的設計結構是簡單的,核心是生產對象。 一般來說,運用工廠模式生產的對象應該是構建對象的過程比較復雜的,獲取構建對象的過程在日後可能發生變更的。 簡單工廠

小胖說事28------iOS中extern,staticconst差別使用方法

方法 string 文件 only 聲明 sans nbsp ring const 通俗的講: extern字段使用的時候,聲明的變量為全局變量,都能夠調用,也有這樣一種比較狹義的說法:extern能夠擴展一個類中的變量到還有一個類中;

python基礎2-靜態方法方法

變量 img 靜態 訪問 func title 改變 參數 code 1. 類方法 是類對象所擁有的方法,需要用修飾器@classmethod來標識其為類方法,對於類方法,第一個參數必須是類對象,一般以cls作為第一個參數(當然可以用其他名稱的變量作為其第一個參數,但是大部

forEachmapfor方法的區別

turn 而不是 ber num 遍歷數組 風格 cnblogs ron () 那麽接下來,我繼續做分析,為什麽更推薦用.map(),而不是.forEach()? 首先,.map()要比.forEach()執行速度更快。雖然我也說過執行速度不是我們需要考慮的主要因素,但是他

為什麽使用 Arrays.asList()得到的集合,使用remove( ) add( )方法會拋出unsupportedoperationexception(不支持操作異常)

操作 err move lan 16px exceptio operation amp span  這是由於:    Arrays.asList() 返回java.util.Arrays$ArrayList, 而不是ArrayList。 Arrays$ArrayList

JavaScript中閉包實現的私有屬性的getter()setter()方法

參數 strong prop nbsp body 利用 edi 獲取 展示 註意: 以下的輸出都在瀏覽器的控制臺中 <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g

反射機制--調用構造函數成員方法、制作幫助文檔

port const center 分享 相關 src -- 知識 water 今天學習了關於反射的相關知識,通過反射能夠找到類中的構造方法和全部的成員方法。而並不了解這個類的構造的人能夠非常方便的運用反射機制。 掌握發射主要了解這幾個類,類位於java.long.re

call 方法 apply方法

his comm 應用 [] () itl new 語法 常用 1、方法定義 call方法: 語法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定義:調用一個對象的一個方法,以另一個對象替換當前對象。 說明: call 方法可以

IP地址的規劃設計方法(三)

情況 網絡 fill 路由 十六進制 fonts 網絡管理 協議 討論 九,內部網絡專用IP地址規劃與網絡地址轉換NAT方法 (1)內部網絡的專用IP地址選擇的根據 RFC1918在討論內部網絡的專用IP地址規劃方法時任務

call apply方法解析

ray ntb 方法 綁定 推斷 都是 還要 new int32 ECAMScript 3給Function的原型定義了兩個方法,它們是Function.prototype.call和Function. prototype.apply。在實際開發中,特別是在一些函數式風格的

uCOS-II中任務優先級的判定處理方法

www 一行 con blog 方法 cloud 問題 找到 引入 轉載請註明原文出處,http://www.cnblogs.com/flyingcloude/p/6992346.html 在uCOS-II中,最多有64個優先級,把這64個優先級每8個分成一組,總