我有一个包含许多活动的应用程序,其中许多活动都使用各种json网络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和教程上找到的许多代码片段相似。问题在于,用户可以在后台进程运行时离开页面。在这种情况下,我收到有关泄漏视图的Logcat错误(ProgressDialog),然后在关闭视图或执行其他UI任务时会崩溃。
我尝试在onSuccess中添加早期检查:
if (!pd.isShowing()) {
return;
}
这样可以修复某些设备上的崩溃,但不能修复其他设备上的崩溃,我们仍然会收到有关泄漏视图的logcat错误。
我尝试用
pd.isShowing()
替换MyActivity.this.isFinishing()
检查,这对任何事情都没有帮助(在我目前正在测试的设备上)。仍然会收到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()
。我没有看到更好的选择,但是在开始更新许多活动之前,我想再说一遍。
最佳答案
创建一个活动,例如NetworkBaseActivity。创建ProgressDialog并在此活动中处理onDestroy。还创建一个名为showMyDialog()
和hideMyDialog()
的方法来显示和隐藏对话框(来自子类)。现在,您所有做后台工作的活动都只需扩展此活动。要显示对话框调用showMyDialog()
并隐藏它,请调用hideMyDialog()
像这样:
public class NetworkBaseActivity extends AppCompatActivity{
ProgressDialog myDialog;
onCreate(Bundle bundle){
// initialize myDialog
}
public void showDialog(){
// show myDialog if not shown
}
public void hideDialog(){
// hide myDialog if already shown
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
public class YourActivity extends NetworkBaseActivity{
}
我直接在stackoverflow中键入了代码,请原谅我的错别字,但是您明白了。