1

多くの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などの予期しない動作が発生します。デバイスがアプリケーションを2回ロードしたいようですが、どれも正常に起動できません。どのように対処するのですか?
再度開始しないように、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();
}

残念ながら、これは何もしません。さらに、同じアプリケーションを2回起動すると、AsyncTaskを「共有」できないため、このようなユースケースが可能かどうかはわかりません。どういうわけか、アプリケーションを2回起動することなどを避ける必要がありますか?これにはどのようなオプションがありますか?何か案は?

4

2 に答える 2

1

私は通常、もう少し率直にそれを行います。AsyncTask使用していないときは、参照をnullに設定しました。火事が起こったらonClick、それがヌルでないかどうかをチェックします。つまり、私はそれを開始しました。nullの場合は、そこで新しいものを作成して実行しますAsyncTask。それは十分に速く、十分にきれいです。このアプローチの利点の1つは、AsyncTask とにかく実行できるのは1回だけなので、それにうまく適合します。の終わりに、同じままにする場合onPostExecuteは、参照を再びに戻すことができます。nullActivity

AsyncTaskフローを完成させている間、方向の変更にも耐えられることを確認してください。

于 2012-11-18T14:04:13.480 に答える
1

私は解決策を見つけました:それは実際にはAsyncTaskの問題ではありません。問題は、processController.initializeData()で呼び出されるJSONParserの解析メソッド(ほとんどの作業を実行する)が同期されていないことでした。

于 2012-11-18T17:40:30.417 に答える