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 dismiss和hide方法的區別
原地址:https://www.pocketdigi.com/20120815/900.html dismiss和hide方法都可以隱藏對話方塊,在需要的時候也可以用show方法呼叫顯示。但是,這兩者是有區別的。 dismiss方法會釋放對話方塊所佔的資源,而hide
web測試中的測試點和測試方法總結
動態 小數 圖片尺寸 提示信息 方便 margin style 容錯性 字符型 測試是一種思維,包括情感思維和智力思維,情感思維主要體現在一句俗語:思想決定行動上(要懷疑一切),智力思維主要體現在測試用例的設計上。具有了這樣的思想,就會找出更多的bug。 一、輸入框
函數中的私有變量和特權方法
getc 單例 隱藏數據 需要 接口 返回對象 div 外部 his 定義 【1】【私有變量】 任何在函數中定義的變量,都可以認為是私有變量,因為不能在函數外部訪問這些變量。私有變量包括函數的參數、局部變量和在函數內部定義的其他函數 【2】【特權方法】 如果在函
[C#學習筆記之異步編程模式2]BeginInvoke和EndInvoke方法 (轉載)
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,static和const差別和使用方法
方法 string 文件 only 聲明 sans nbsp ring const 通俗的講: extern字段使用的時候,聲明的變量為全局變量,都能夠調用,也有這樣一種比較狹義的說法:extern能夠擴展一個類中的變量到還有一個類中;
python基礎2-靜態方法和類方法
變量 img 靜態 訪問 func title 改變 參數 code 1. 類方法 是類對象所擁有的方法,需要用修飾器@classmethod來標識其為類方法,對於類方法,第一個參數必須是類對象,一般以cls作為第一個參數(當然可以用其他名稱的變量作為其第一個參數,但是大部
forEach和map和for方法的區別
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個分成一組,總