如何从Runnable检测活动是否处于可用状态?

时间:2011-03-21 15:02:38

标签: android service android-activity

我有一个正在执行数据更新的服务。我有一个活动,它将一个监听器附加到服务上(通过本地绑定)。监听器接收进度更新。收到进度更新后,它会调度可在UI线程上运行的runnable。这是代码(更新以显示完整列表):

public class MyActivity extends Activity {

  static final int UPDATE_DIALOG = 0;
  ProgressDialog updateDialog;

  private TaskService taskService;

  private ServiceConnection taskServiceConnection = new ServiceConnection() {

    private final TaskServiceObserver taskServiceObserver = new TaskServiceObserver() {

      public void updateProgress(final int progress, final int total) {
        runOnUiThread(new Runnable() {
          public void run() {          
            if (updateDialog == null || !updateDialog.isShowing()) {
              showDialog(UPDATE_DIALOG);
            }
            updateDialog.setProgress(progress);
          }
        });
      }

      public void updateCompleted() {
        runOnUiThread(new Runnable() {
          public void run() {  
            dismissDialog(UPDATE_DIALOG);
            startNextActivity();
          }
        });
      }
    };

    public void onServiceConnected(ComponentName name, IBinder binder) {
      taskService = ((LocalBinder) binder).getService();

      taskService.addObserver(taskServiceObserver);
    }

    public void onServiceDisconnected(ComponentName name) {
      taskService.removeObserver(taskServiceObserver);
      taskService = null;
    }

  };

  protected void onStart() {
    super.onStart();

    Intent intent = new Intent(this, TaskService.class);
    startService(intent);
    bindService(intent, taskServiceConnection, Context.BIND_AUTO_CREATE);
  }

  protected void onStop() {
    super.onStop();

    if (taskService != null) {
      unbindService(taskServiceConnection);
    }
  }

  protected Dialog onCreateDialog(int id) {
    switch (id) {
    case UPDATE_DIALOG:
      updateDialog = new ProgressDialog(this);
      updateDialog.setTitle("My App");
      updateDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
      updateDialog.setMessage("Preparing to run for the first time...");
      return updateDialog;
    default:
      return null;
    }
  }

}

如果在对话框显示时点击主页按钮,然后返回应用程序,我会在showDialog行发生崩溃。通过调试器,我能够确定活动处于完成状态。

什么是适当的检查以放入我的runnable,这将决定是否可以安全地拨打showDialog

3 个答案:

答案 0 :(得分:0)

当活动进入暂停状态时,我会逐渐关闭进度对话框(覆盖onPause),并在活动恢复时重新创建它(覆盖onResume)。您可以通过在其他单独的对象(对话框)中保留对活动的引用来泄漏内存

答案 1 :(得分:0)

您应该在onPause方法中分离侦听器,以便由于您的活动进入后台,侦听器将不会触发并尝试更新UI。

答案 2 :(得分:0)

我最终得到的解决方案是创建一个标志taskServiceBound,在绑定到onStart中的服务后设置为true,并在从{{1}中的服务解除绑定之前设置为false }。因为该标志在UI线程上更新,所以我可以使用它在onStopupdateProgress中为Runnables设置门户。例如:

updateCompleted