(转)ProgressDialog的hide()和dismiss()方法

来源:互联网 发布:淘宝小号怎么申请 编辑:程序博客网 时间:2024/06/02 20:36

原地址:http://blog.csdn.net/u014302433/article/details/50544566


在使用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();        }       }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

上面注释是异常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);        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在看下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();        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

看到了mWindowManager.removeViewImmediate(mDecor)的代码。 
至此,dialog的view才被真正移除。 
希望小伙伴们不要犯和我一样的low的错误。。。


0 0
原创粉丝点击