我有一个包含许多活动的应用程序,其中许多活动都使用各种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()
。
我没有找到更好的选择,但是在开始更新许多活动之前,我需要第二意见。
答案 0 :(得分:1)
创建一个活动,例如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中输入了代码,请原谅我的错别字,但您明白了。