Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android AsyncTask在一次又一次地按Home按钮时不协调_Android_Concurrency_Android Asynctask_Runtimeexception - Fatal编程技术网

Android AsyncTask在一次又一次地按Home按钮时不协调

Android AsyncTask在一次又一次地按Home按钮时不协调,android,concurrency,android-asynctask,runtimeexception,Android,Concurrency,Android Asynctask,Runtimeexception,我有一个AsyncTask,它执行大量JSON计算 public class InitializationTask extends AsyncTask<Void, Void, InitializationResult> { private ProcessController processController = new ProcessController(); private ProgressDialog progressDialog; private Ma

我有一个AsyncTask,它执行大量JSON计算

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();
        }
    }
}

不幸的是,这没有任何作用。此外,我不确定这样的用例是否可行,因为当我启动同一个应用程序两次时,它们无法“共享”异步任务。我是否应该避免启动应用程序两次?我不确定我有什么选择?有什么想法吗?

我通常会更直截了当一点。当我不使用时,我将我的
AsyncTask
引用设置为null。当点击
onClick
时,我检查它是否为空,这意味着我启动了它。如果为空,我就在那里创建并执行一个新的
AsyncTask
。它非常快,而且足够干净。这种方法的一个好处是,
AsyncTask
无论如何只能执行一次,因此它非常适合这种情况。在
onPostExecute
的末尾,如果您想保持在相同的
活动中,可以再次将引用设置回
null


在完善AsyncTask流程的同时,请确保它也是如此。

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

你是说onCreate而不是onClick?我认为我的问题不同。任务调用的方法由于NullPointerException或JSON框架引起的异常而不同步。这些方法似乎仍然以某种方式执行,但由于任务取消而导致数据损坏……顺便说一句:在链接的代码示例中使用的getLastNonConfigurationInstance()已被弃用。@Bevor--当然,我完全知道这一点。这并没有改变这样一个事实,即在野外仍然有代码使用这种方法。无论如何,你需要注意方向的改变如果您是在活动中声明一个异步任务,而不是一个片段,那么在方向更改中保持它的最佳方法是使用上述方法中阐述的方法。您可以指出该方法已被弃用,但现在您正在以依赖弃用方法正常工作的方式编写代码(或使用服务,这是另一种对话)。您所说的“以依赖弃用方法的方式编写代码”到底是什么意思。我的代码中不推荐的具体内容是什么?还要确保在onPause之后任务不会继续运行。@Tom Dignan好的,我会记住它。processController.initializeData()是否在单独的线程上运行?您不需要这样做,因为已经在线程池中为您调用了doInBackground。onPreExecute、doInBackground和onPostExecute将始终一个接一个地执行,doInBackground在单独的线程上执行,另外两个在主/UI线程上执行。@Tom Dignan否,processController.initializeData()不是单独的线程。问题是JSONSimple.parse没有同步,这就是为什么我必须同步我的parse方法,它使用这个方法。主要的问题是解析大约需要20秒,当我启动一个新的异步任务时,而之前的解析还没有完成,一个非同步的解析方法无法处理这个问题。当我同步它时,它就不再稳定了。(我也使用了你链接的代码,也许两者的结合才是正确的解决方案)
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();
}