4

長時間実行されるタスクを開始するボタンのあるアクティビティがあります。AsyncTaskを使用してタスクを実行し、タスクの進行に応じて更新される確定的なProgressBarを表示します。タスクを最初に実行したときはすべて正常に機能しますが、その後の実行ではダイアログが表示されますが、すでに100%および100/100になっています。アクティビティでonCreateDialogとonPrepareDialogの両方をオーバーライドしています。setProgress(0)を使用するとダイアログがリセットされると思いましたが、これは機能していません。AsyncTaskのonPreExecuteメソッドでshowDialogを使用し、AsyncTaskのonPostExecuteでdismissDialogを使用します。ダイアログをリセットする唯一の方法は、onPostExecuteでremoveDialogを使用することですが、何度か再利用するため、ダイアログを再作成したくありません。関連するコードは以下のとおりです。これはAPIレベル10です。

@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
        case PROGRESS_DIALOG:
            progressDialog = new ProgressDialog(ProtoBufSerializationTestActivity.this);
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progressDialog.setCancelable(true);
            progressDialog.setMax(100);
            progressDialog.setMessage("Testing...");
            return progressDialog;
        default:
            return null;
    }
}

@Override
protected void onPrepareDialog(int id, Dialog dialog) {
    super.onPrepareDialog(id, dialog);
    switch (id) {
        case PROGRESS_DIALOG:
            ProgressDialog tmp = (ProgressDialog)dialog;
            tmp.setProgress(0);
            tmp.setSecondaryProgress(0);
            return;
        default:
            Log.e("test", "Unknown dialog requested");
    }
}

private class SerializationTestTask extends AsyncTask<Void, Integer, Long> {

    @Override
    protected void onPreExecute() {
        showDialog(PROGRESS_DIALOG);
    }

    @Override
    protected Long doInBackground(Void... params) {
        long accumulator = 0;
        int totalSize = 0;
        for (int i = 0; i < 10000; i++) {
            final long start = System.nanoTime();
            //code to be timed
            final long end = System.nanoTime();
            accumulator += end - start;
            if (i % 100 == 0) {
                publishProgress(i);
            }
        }
        return accumulator;
    }

    @Override
    protected void onPostExecute(Long aLong) {
        dismissDialog(PROGRESS_DIALOG);
        results.setText(String.format("Serialized Message 10000 times.\nAverage time to serialize %.3fms", (double) aLong / 1e10));
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        progressDialog.incrementProgressBy(1);
    }

編集@Arhimedの提案を受けた後、私は次のコードになりました。それははるかに簡単です。使用できたかもしれDialogFragmentませんが、この場合は必要ないと思います。

private class SerializationTestTask extends AsyncTask<Void, Integer, Long> {
    private ProgressDialog dialog;

    @Override
    protected void onPreExecute() {
        dialog = ProgressDialog.show(ProtoBufSerializationTestActivity.this, "Serialization Test", "Testing...", false);
    }

    @Override
    protected Long doInBackground(Void... params) {
        long accumulator = 0;
        int totalSize = 0;
        for (int i = 0; i < 10000; i++) {
            final long start = System.nanoTime();
            //code to be timed
            final long end = System.nanoTime();
            accumulator += end - start;
            if (i % 100 == 0) {
                publishProgress(i);
            }
        }
        return accumulator;
    }

    @Override
    protected void onPostExecute(Long aLong) {
        dialog.dismiss();
        results.setText(String.format("Serialized Message 10000 times.\nAverage time to serialize %.3fms", (double) aLong / 1e10));
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        dialog.incrementProgressBy(1);
    }
}
4

3 に答える 3

2

実際、Arhimedは正しく、それを行うことはできませんが、プログレスバーを「ダーティ」な方法で強制的にゼロ状態にすることができます。私にとって、クライアントは、ユーザーがそれを離れた場合に備えて、プログレスバーの値をゼロにすることを望んでいました。アクティビティですが、私の場合、進行状況はまだそこにあり、最初からリセットされただけでした。カスタムの進行状況ドローアブルがあり、setProgressまったく役に立ちませんでした。したがって、実際にREALドローアブルを設定する前にこのメソッドを呼び出すと、setProgressDrawable(null)これはダーティです。方法をクリアしますが、それはあなたが望むことをします、そしてその後あなた自身のプログレスドローアブルで同じメソッドを呼び出すだけでそれはリフレッシュされたように感じますそれはそれです..残念ながらこれを達成することができる他の方法はありません。

于 2015-10-27T08:45:08.477 に答える
1

そのように使うことは不可能ProgressDialogです。毎回AsyncTask新しいインスタンスを作成する必要があります。

于 2012-06-27T21:20:54.237 に答える
0

実際、setProgress(0)は、進行状況が開始された場合にのみ表示を更新します。したがって、次のように、setProgressの前にonStartを呼び出すことで、強制的に更新できます。

@Override
protected void onPrepareDialog(int id, Dialog dialog) {
    super.onPrepareDialog(id, dialog);
    ProgressDialog progress = (ProgressDialog)dialog;
    progress.onStart();
    progress.setProgress(0);
}
于 2014-07-30T14:15:06.933 に答える