0

私のAndroidアプリケーションは、読み込みダイアログを表示しながら、必要なすべてのデータを読み込むことから始めます。

// Load data in background, while updating the loading dialog.
(new AsyncTask<Void, String, Void>() {
    @Override
    protected Void doInBackground(Void... params) {
        publishProgress(getString(R.string.loading_a));
        if!(loadA())
            showErrorDialogAndQuit();
        publishProgress(getString(R.string.loading_b));
        if(!loadB())
            showErrorDialogAndQuit();
        publishProgress(getString(R.string.loading_c));
        if(!loadC())
            showErrorDialogAndQuit();
        return null;
    }

    protected void onProgressUpdate(String... progress) {
        dialog.setMessage(progress[0]);
    }

    protected void onPostExecute(Void result) {
        // Update the UI.
        updateUI();
        dialog.dismiss();
    }
}).execute();

メソッドloadA()、、loadB()およびloadC()は失敗する可能性があり、falseを返します。この時点で、エラーメッセージを表示し、アプリケーションをメソッドで終了させたいと思いますshowErrorDialogAndQuit()

次のように作成してみましたが、アプリケーションが終了した後は常にエラーが発生するようです。これは、読み込みダイアログにウィンドウがないことと関係があります。

public void showErrorDialogAndQuit() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            AlertDialog aDialog = new AlertDialog.Builder(MyActivity.this).setMessage("Fatal error.").setTitle("Error")
                    .setNeutralButton("Close", new AlertDialog.OnClickListener() {
                        public void onClick(final DialogInterface dialog, final int which) {
                            // Exit the application.
                            finish();
                        }
                    }).create();
            aDialog.setOnKeyListener(new OnKeyListener() {
                @Override
                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                    // Disables the back button.
                    return true;
                }

            });
            aDialog.show();
        }
    });
}

これを達成するための最良の方法は何ですか?

4

2 に答える 2

0

私がする必要があるのは、finish()呼び出される前に進行状況ダイアログを自然に閉じることだけでした。

if(!loadA()) {
    showErrorDialogAndQuit();
    return null;
}

これは、別のスレッドで実行されるエラーダイアログを作成し、nullを返しAsyncTaskて実行させonPostExecute()、進行状況ダイアログを閉じることで機能します。次に、エラーダイアログの閉じるボタンを押してfinish()呼び出すと、すべてが正しく閉じることができました。

このアプローチの唯一の欠点は、UIの更新よりも実質的な何かがで起こっていた場合ですonPostExecute()。その場合、引数の型を変更してテストし、何をすべきかを確認できます。

于 2012-04-17T23:55:30.813 に答える
0

loadAが成功した後にのみloadBを実行できる場合は、コードのロジックを変更することをお勧めします。stateAが終了した後にstateBがトリガーされる3つの状態でのファイナルステートマシンアプローチを使用できます。

また、UIの更新は、ハンドラーを使用してうまく行うことができます。ロジックは次のようになります。

  1. 本体でスレッドローディングを開始A
  2. threadAで、成功した場合はmsg A_successを本体に送信し、そうでない場合はmsgA_failedを本体に送信します。threadAはここで終了します。
  3. 本体はハンドラーを介してメッセージを受信し、受信した場合は続行しますA_success->スレッドの読み込みを開始しますBそれ以外の場合は終了します(または必要なものは何でも)

threadAの開始は次のようになります。

  new Thread(new Runnable() {
    public void run() {
        loadingA();
    }
    }).start();

LoadingA内で、次のようにメッセージを本体に送り返します。

 public void loadingA() {
    ...do your loading...

    then to inform the main body...

    Message msg = mHandlerToReceiveTheResultFromLoadingThread
            .obtainMessage(MESSAGE_UPDATE_RESULT_OF_LOADING_A);
        Bundle bundle = new Bundle();
        bundle.putBoolean(RESULT_OK_INFO, true or false);
        msg.setData(bundle);
        mHandlerToReceiveTheResultFromLoadingThread
            .sendMessage(msg);

        }

本体ではmHandlerToReceiveTheResultFromLoadingThread次のようになります。

public final Handler mHandlerToReceiveTheResultFromLoadingThread = new Handler() {
    @Override
    public void handleMessage(Message msg) {

        if (DEBUG)
        Log.i(this.getClass().getSimpleName(),
            "-> "
                + Thread.currentThread().getStackTrace()[2]
                    .getMethodName() );
        switch (msg.what) {
        case MESSAGE_UPDATE_RESULT_OF_LOADING_A: {
        boolean result_ok = msg.getData().getBoolean(RESULT_OK_INFO);

        if (result_ok)
            ...continue with loadingB;
            else
               show your message that it failed and exit;
        }
        break;

        }

    }

お役に立てれば...

編集:アクティビティのロジックの最後でfinishを呼び出す:

        this.myBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {   
                String msg = "Hello, I have finished and started another activity";
                doOtherActivit(msg); 
                finish();
            }
        });
    }

public void doOtherActivity(String msg) {
        Intent i;
        i = new Intent(this, OtherActivity.class);
        i.putExtra("Task", msg);        
        startActivity(i);
    }
于 2012-04-17T21:27:56.337 に答える