【发布时间】:2019-02-25 09:41:11
【问题描述】:
我有一个包含许多活动的应用程序,其中许多活动使用各种 json Web API 来加载和显示数据。一个常见的模式类似于:
public class MyActivity extends Activity {
public void OnCreate(Bundle savedInstanceState) {
...
ProgressDialog pd = ProgressDialog.show( ... );
// This is a custom API which wraps AsynkTask and calls my callback in onPostExecute
DoWebThing(url, new Callback() {
public void onSuccess(String json) {
pd.dismiss();
// Do other UI stuff with the json data
}
});
}
}
这很好用,并且类似于您在 SO 和教程中找到的许多代码 sn-ps。问题是用户可以在后台进程运行时离开页面。在这种情况下,我收到有关泄漏视图(ProgressDialog)的 logcat 错误,然后当我关闭它或执行其他 UI 操作时我会崩溃。
我已尝试在 onSuccess 添加提前签入:
if (!pd.isShowing()) {
return;
}
这修复了某些设备上的崩溃问题,但没有解决其他设备上的崩溃问题,我们仍然会收到有关泄漏视图的 logcat 错误。
我尝试用MyActivity.this.isFinishing() 替换pd.isShowing() 检查,这对任何事情都没有帮助(在我目前正在测试的设备上)。仍然得到 logcat 错误并崩溃。
我尝试了MyActivity.this.isDestroyed(),它修复了崩溃,但仅适用于 SDK 17+ 并且仍然出现 logcat 错误。
真正解决这个问题的唯一选择是让我的进度对话框成为成员变量并覆盖OnDestroy():
ProgressDialog mPd;
@Override
protected void onDestroy() {
super.onDestroy();
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
现在在我的回调中我可以检查mProgressDialog == null。
这很好用。没有崩溃,也没有关于泄漏视图的 logcat 错误。但这感觉像是很多样板——我必须将进度对话框设为成员变量,并在我所有(许多)执行后台操作的活动中覆盖 OnDestroy()。
我没有看到更好的选择,但在我开始更新大量活动之前想征求第二意见。
【问题讨论】:
-
最好继续使用实时数据和架构组件
标签: android android-activity android-asynctask progressdialog