避免使用ProgressDialog和AsyncTask做样板吗?

时间:2018-09-21 02:48:40

标签: android android-activity android-asynctask progressdialog

我有一个包含许多活动的应用程序,其中许多活动都使用各种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()

我没有找到更好的选择,但是在开始更新许多活动之前,我需要第二意见。

1 个答案:

答案 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中输入了代码,请原谅我的错别字,但您明白了。