【问题标题】:ProgressDialog.show takes 1.5 minutes to returnProgressDialog.show 需要 1.5 分钟才能返回
【发布时间】:2015-07-08 18:51:31
【问题描述】:

我们早在 10 月份就开发了一个新版本的应用程序,当时没有注意到这个问题,所以可能没有发生。这段代码没有改变,但改变的是Android的版本。我们甚至在运行 4.4.2 的设备上看到了这种情况,所以这不仅仅是棒棒糖的问题。

我有一个“静态”类,它在整个应用程序中用于显示和关闭进度对话框。该类的相关方法包含在下面的代码块中。我已经围绕有问题的 API 调用添加了一些时间,并且还包括了几个调用的结果。 progressDialog 是类上的一个静态字段,用于跟踪当前打开的对话框,以便将其关闭。

/**
 * Shows the progress dialog box, allowing for the message and title to be supplied.
 * The progress dialog will be indeterminate and not cancelable.
 *
 * @param context The context that owns the dialog.
 * @param message The message to display in the dialog.
 * @param title   The title for the dialog box.
 */
public static void showProgressDialog ( Context context, String message, String title ) {
    closeProgressDialog();
    String actualTitle = OverrideProgressDialogTitle ? DefaultProgressDialogTitle : title;
    String actualMessage = OverrideProgressDialogMessage ? DefaultProgressDialogMessage : message;

    Date start = new Date();
    progressDialog = ProgressDialog.show( context, actualTitle, actualMessage, true, false );
    Date end = new Date();

    Log.v( LogTag, String.format("It took %s minutes to show the dialog.", DateUtils.millisecondsToMinutes( end.getTime() - start.getTime() ) ) );
}

/**
 * Closes the progress dialog box if it is opened.
 */
public static void closeProgressDialog () {
    if ( progressDialog != null && progressDialog.isShowing() ) {
        try {
            progressDialog.dismiss();
        }
        catch ( Exception e ) {
            Log.e( LogTag, "Error closing dialog.", e );
        }
    }
    progressDialog = null;
}

以下是一些时间安排:

It took 0.0013666668 minutes to show the dialog. 
It took 3.8333333E-4 minutes to show the dialog. 
It took 3.6666667E-4 minutes to show the dialog. 
It took 1.4308 minutes to show the dialog.

结果非常可重复...第一次在应用程序中的 2 个特定屏幕上显示对话框时,从调用 ProgressDialog.show 返回大约需要 1.5 分钟,但随后调用显示来自那些对话框同样的地方几乎立即返回。在一种情况下,从片段的 onStart 方法显示对话框以加载数据,在另一种情况下,当单击将数据提交到服务器的按钮时显示该对话框。

有没有人觉得这个方法调用需要很长时间才能返回,如果是这样,你是如何解决的?

编辑:我实际上对此进行了进一步的追踪,这是导致挂断的其他问题。 AsyncTask 的 onPreExecute 方法完成和 doInBackground 开始之间有时似乎有很长的延迟。

【问题讨论】:

  • 持有对 ProgressDialog 的静态引用会泄露 Activity 上下文,这可能会导致各种麻烦。
  • 对话框总是在同一个活动中打开和关闭,所以应该没有泄漏。

标签: android


【解决方案1】:

几周前发生在我身上。

在某些设备上,静态显示Dialog 会引起很多痛苦,而在其他设备上则不会。

它与正在使用的Context 直接相关。

我建议您不要使用 ProgressDialog,而是创建自己的 DialogFragment 并使用 FragmentManager 来显示或隐藏它。

它为我解决了同样的问题。

【讨论】:

    【解决方案2】:

    你检查了吗 Progress dialog UI Freezes/SlowProgressdialog slow to show in Android ? 这很可能是线程问题。如:您可能正在从后台线程调用显示/隐藏。

    [原始帖子:] 跟踪进度对话框的静态类是糟糕的设计。不要这样做。

    您不应该从(可能)不同的上下文中关闭进度对话框,因为它们可能位于不同的视图层次结构中(附加到不同的 Activity),并且该视图层次结构可能已经被销毁/分离。

    【讨论】:

    • 我不同意按照 DRY 删除重复的样板代码和逻辑是糟糕的设计。我知道如果使用不当可能会出现泄漏等问题,但对话框总是在同一上下文中打开和关闭。这不应该是我们看到的问题的原因。
    • 我不反对 DRY。 DRY 可以在不跟踪对话实例的情况下实现。有很多方法可以减少样板代码,但是以这种方式跟踪上下文绑定实例只是糟糕的代码设计。您应该以不会错误使用它的方式来设计您的代码 - 或者当它被错误使用时,您可以清楚地提供错误的反馈(例如通过异常抛出)。在任何情况下:任何不明显和自记录的东西都应该用 javadoc 清楚地记录。
    • 我不是在捍卫或宽恕我使用静态类来管理进度对话框,但这里是我以这种方式使用它的原因和方式。我认为这是一个非常标准的模式,活动或片段在启动/恢复或响应某些用户交互时执行网络操作。此应用程序使用 AsyncTasks 执行此操作,并在 onPreExecute 中显示进度对话框。在 onPostExecute 中,进度对话框被关闭,消息被发送到处理程序。如果需要对显示的进度对话框进行全局更改,可以在一个地方完成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-10
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    相关资源
    最近更新 更多