当一次又一次地按下Home按钮时,AsyncTask失去了步骤

时间:2012-11-16 21:19:19

标签: android concurrency android-asynctask runtimeexception

我有一个执行大量JSON计算的AsyncTask。

public class InitializationTask extends AsyncTask<Void, Void, InitializationResult> {
    private ProcessController processController = new ProcessController();
    private ProgressDialog progressDialog;
    private MainActivity mainActivity;

    public InitializationTask(MainActivity mainActivity) {
        this.mainActivity = mainActivity;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        progressDialog = new ProgressDialog(mainActivity);
        progressDialog.setMessage("Die Daten werden aufbereitet.\nBitte warten...");
        progressDialog.setIndeterminate(true); //means that the "loading amount" is not measured.
        progressDialog.setCancelable(false);
        progressDialog.show();
    };

    @Override
    protected InitializationResult doInBackground(Void... params) {
        return processController.initializeData();
    }

    @Override
    protected void onPostExecute(InitializationResult result) {
        super.onPostExecute(result);

        progressDialog.dismiss();

        if (result.isValid())  {
            mainActivity.finalizeSetup();
        }
        else  {
            AlertDialog.Builder dialog = new AlertDialog.Builder(mainActivity);
            dialog.setTitle("Initialisierungsfehler");
            dialog.setMessage(result.getReason());
            dialog.setPositiveButton("Ok",
                    new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.cancel();

                            mainActivity.finish();
                        }
                    });

            dialog.show();
        }
    }
}

processController.initializeData()运行大约20秒。这一切都有效。它甚至在我安装应用程序时起作用,并在应用程序初始化时按下主页按钮。 AsyncTask正在后台工作。当我在AsyncTask完成后再次从Android设备重新启动应用程序时,应用程序仍可正常工作。
但是应用程序无法处理这种用例:当我部署应用程序时(或者在没有数据初始化时启动它),因此初始化数据真的需要大约20秒,当我在初始化时回到主页关闭应用程序时(AsyncTask) )在后台运行并再次启动应用程序,它会导致RuntimExceptions等意外行为。设备似乎想要加载应用程序两次,但它们都不能成功启动。如何处理?
我考虑过检查MainActivity中是否存在正在运行的AsyncTask以避免再次启动它:

private InitializationTask initializationTask = new InitializationTask(this);

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    if (!AsyncTask.Status.RUNNING.equals(initializationTask.getStatus()))  {
        initializationTask.execute((Void[])null);
    }

    initializeMap();
}

不幸的是,这确实无能为力。此外,我不确定这样的用例是否可行,因为当我两次启动相同的应用程序时,他们无法“共享”AsyncTask。我应该以某种方式避免启动应用程序两次或什么?我不确定我对此有什么选择?有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我通常会直言不讳地说。当我不使用它时,我将AsyncTask引用设置为null。当onClick触发时,我检查它是否为空,这意味着我启动了它。如果它为null,我在那里创建并执行一个新的AsyncTask。它速度快,而且足够干净。这种方法的一个好处是AsyncTask 只能执行一次,所以它很适合。在onPostExecute结束时,如果您打算保持同一null,则可以将参考设置重新设置为Activity

在完善AsyncTask流程时,请确保它survives orientation changes

答案 1 :(得分:1)

我找到了解决方案:它实际上不是AsyncTask问题。问题是我在processController.initializeData()中调用的JSONParser的解析方法(它完成了大部分工作)没有同步。