为什么在显示AlertDialog之前需要延迟?

时间:2015-05-03 17:25:32

标签: android alertdialog ui-thread

在某些情况下,当我的应用启动时,会显示AlertDialog。但是,警报永远不会显示。我发现如果我添加一个延迟,它就可以工作(即显示)。

更具体地说:在应用启动时,它会执行主要活动onCreate(),在某个条件下启动第二个活动。在第二个活动中,通过一个单独的线程,它检查一些Web服务器状态。如果Android设备没有Internet连接,HttpURLConnection会立即返回错误,我的封闭函数会执行第二个活动的回调。我的代码然后使用post()尝试向用户显示警报(使用post允许在UI线程上显示警报,这是必需的)。

显然,它会尝试在创建任何一个活动的UI之前显示警报。如果我在第二个活动中使用postDelayed(),问题仍然存在。但是,如果我在主活动中使用以下代码块,则警报会正确显示:

new Handler().postDelayed (new Runnable ()
{
  @Override public void run()
  {
    Intent intent = new Intent (app, MyClass.class);
    app.startActivityForResult (intent, requestCode);
  }
}, 3000);

我的解决方案是一个恰好在此刻工作的黑客攻击。我不介意在这种特殊情况下对启动有一点延迟,但我不希望延迟超过必要时间或有时会失败。

什么是正确的解决方案?

1 个答案:

答案 0 :(得分:0)

好的,这是一个解决方法。首先,我推测问题是在UI线程的looper启动之前发生了显示警报的尝试。只是猜测。

要解决这个问题,我添加了一个从onResume()调用的递归帖子,如下所示:

private boolean paused = true;

@Override public void onResume ()
{
  super.onResume();
  paused = false;
  checkForAlert();
}

@Override public void onPause ()
{
  super.onPause();
  paused = true;
}

以下是发布帖子的功能:

private AlertInfo alertInfo = null;

private void checkForAlert()
{
  if (alertInfo != null)
  {
    ...code to build alert goes here...
    alertInfo = null;
  }

  if (!paused)
    contentView.postDelayed (new Runnable()
    {
      @Override public void run() { checkForAlert(); }
    }, 200);
}

AlertInfo是一个简单的类,其中需要警报的线程可以放置相关信息,例如标题,消息。

那么,这是如何工作的? checkForAlert()在onResume()期间被调用,并将继续每200ms调用一次,直到“paused”为false,这发生在onPause()中。只要显示活动,就可以保证重复出现。如果alertInfo不为null,则会生成并显示警报。在辅助线程中,我只创建一个AlertInfo实例,然后在200ms内显示警报。 200ms足够短,大多数人都不会注意到延迟。它可能会更短,但电池使用量会增加。

为什么我在onResume而不是onCreate()中启动checkForAlert()?仅仅因为除非活动目前处于“顶部”,否则不需要它运行。这也有助于延长电池寿命。