我有一个正在执行数据更新的服务。我有一个活动,它将一个监听器附加到服务上(通过本地绑定)。监听器接收进度更新。收到进度更新后,它会调度可在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
?
答案 0 :(得分:0)
当活动进入暂停状态时,我会逐渐关闭进度对话框(覆盖onPause
),并在活动恢复时重新创建它(覆盖onResume
)。您可以通过在其他单独的对象(对话框)中保留对活动的引用来泄漏内存
答案 1 :(得分:0)
您应该在onPause方法中分离侦听器,以便由于您的活动进入后台,侦听器将不会触发并尝试更新UI。
答案 2 :(得分:0)
我最终得到的解决方案是创建一个标志taskServiceBound
,在绑定到onStart
中的服务后设置为true,并在从{{1}中的服务解除绑定之前设置为false }。因为该标志在UI线程上更新,所以我可以使用它在onStop
和updateProgress
中为Runnables设置门户。例如:
updateCompleted