【问题标题】:Android ProgressDialog: Leaked windowAndroid ProgressDialog:泄漏的窗口
【发布时间】:2011-08-07 00:49:51
【问题描述】:

我有一个带有 Tabhost 的 Activity,所有选项卡都由 Activity 表示,其中一个称为 BrowserTab。

所有这些活动都观察一个 Observable 类,Data。

在 BrowserTab 中,我调用 Data 中的一个方法,该方法从 Internet 检索一些数据。 我想在调用此方法时使用 ProgressDialog 通知用户。 我试过这样:

在浏览器选项卡中:

public void loadXML(){
    progressDialog = ProgressDialog.show(this, "", "Loading. Please wait...", true);
    data.loadXML(getUrl());
}

public void update(Observable o, Object arg)
{
    progressDialog.dismiss();
}

在数据中:

public void loadXML(String url)
{
    this.xml = new XMLParser().parse(url);
    setChanged();
    notifyObservers();

}

像这样,ProgressDialog 会在加载后出现,然后立即消失。

当我在 Data 中的 loadXML(String url) 方法中创建一个新线程时,当通知观察者时,我得到一个“Activity has leaked window”异常。

我已经搜索过这个问题的解决方案,但我就是不知道如何解决这个问题。 有人有想法吗?

【问题讨论】:

    标签: android progressdialog


    【解决方案1】:

    尝试用这个来改变你的代码..

    progressDialog = ProgressDialog.show(getParent(), "", "Loading. Please wait...", true);
    

    【讨论】:

      【解决方案2】:

      旧答案:: 请检查上次编辑

      答案是使用 this.getApplicationContext() 而不是 this

      progressDialog = ProgressDialog.show(this.getApplicationContext(), "", "Loading. Please wait...", true);
      

      更多解释在这里:

      ProgressDialog : how to prevent Leaked Window

      编辑

      后来我发现 this.getApplicationContext()

      总是等于null,所以我使用了DialogFragment并为其添加了一个ProgressBar,而不是使用普通的ProgressDialog

      编辑 2 这个answer 更好,因为它解决了根本原因。也就是说,承载对话框的窗口在对话框之前被关闭,所以只需要求活动在被关闭之前关闭对话框

      【讨论】:

        【解决方案3】:

        对于这个问题,我总是使用基于 C++ 的样式方法。因此,您应该使用进度对话框的 WeakReference(在 C++ 中您有 TWeakObjectPtr)。在分离的线程、asyncTask 等中使用 Wea​​kReference 可确保如果某个参与者作为 GC 清除您的引用,WeakReference.get() 将返回 null。因此,您可以推断您即将使用泄漏的窗口...

        这就是它的工作原理。我们可以如下说明一个基于 asyncTask 的构造函数...

            private WeakReference<ProgressDialog> progressDialog;
            private final FinishListener listener;
        
            public SaveDataTask(ProgressDialog progressDialog,
                                 @NonNull FinishListener listener) {
                this.progressDialog = new WeakReference<>(progressDialog);
                this.listener = listener;
            }
            ...
            @Override
            protected void onPostExecute(Boolean success) {
                if (progressDialog.get() != null) {
                    progressDialog.get().cancel();
                }
                listener.onSaveFinish()
           }
        

        希望对你有帮助

        【讨论】:

          猜你喜欢
          • 2011-09-30
          • 1970-01-01
          • 2013-12-23
          • 2012-02-14
          • 1970-01-01
          • 2014-05-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多