9

私のアクティビティにはProgressBarがあります。アクティビティを開始するときに、別の場所から取得した値を確認し、ProgressBarに更新します。これが私のコードです:

final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar_detail);
final TextView progressText = (TextView) findViewById(R.id.progressText_detail);
final ImageView btnCancel = (ImageView) findViewById(R.id.imgCancel_detail);
progressBar.setVisibility(View.VISIBLE);
progressText.setVisibility(View.VISIBLE);
btnCancel.setVisibility(View.VISIBLE);
Thread t = new Thread() {
    public void run() {
        ((Activity) ctx).runOnUiThread(new Runnable() {
            public void run() {
                int oldProgress = 0;
                while (progressBar.getProgress() < 100) {
                    int value = Downloader.progress.get(gameId+ "");
                    if (value != oldProgress) {
                        oldProgress = value;
                        progressBar.setProgress(value);
                        progressText.setText(value + " %");
                    }
                }
            }
        });
    }
};
t.start();

ProgressBarの値は、私が取得したものint value = Downloader.progress.get(gameId)であり、正しいものです。しかし、このコードを実行すると、アクティビティが応答せず、何も表示されません(ただし、アプリはクラッシュしません)。実行中のProgressBarを更新し、UIスレッドをブロックして、アクティビティレイアウトが表示されないようにするスレッドのようです。

私のコードの何が問題になっていますか?この状況でProgressBarを更新する正しい方法は何ですか?

4

4 に答える 4

12

UI スレッドでを実行しているためwhile (progressBar.getProgress() < 100)( を使用runOnUiThread)、このループが終了するまで UI スレッドはブロックされます (何も描画されません)。

あなたはできる:

  • をループの中に入れてrunOnUiThread、おそらく de runOnUiThreadcall の中にスリープを入れます。ただし、値の変更を探すだけで CPU を使いすぎているため、推奨される種類のソリューションではありません。スリープは少し醜いアプローチですが、CPUの問題は解決します。それは次のようになります::

    Thread t = new Thread() {
        public void run() {
        int oldProgress = 0;
    
        while (progressBar.getProgress() < 100) {
                ((Activity) ctx).runOnUiThread(new Runnable() {
                    public void run() {
                        int value = Downloader.progress.get(gameId+ "");
                        if (value != oldProgress) {
                            oldProgress = value;
                            progressBar.setProgress(value);
                            progressText.setText(value + " %");
                        }
                    }
                }
                Thread.sleep(500);
            }
        });
      }
    };
    
  • イベントの方法で進行状況バーを更新して、進行状況が変化したときにのみ (UI スレッドで) 更新コードを呼び出すようにします。これは好ましい方法です。

于 2012-07-10T09:07:36.877 に答える
2

試してみてください:

    int currentPosition=0;
    int total=mediaPlayer.getDuration();
    while(mediaPlayer!=null && currentPosition<total){
        try{
            if(progressEnable){
                Thread.sleep(1000);
                currentPosition=mediaPlayer.getCurrentPosition();
                long pos=1000L * currentPosition/total;
                Log.d("thread pos", pos+"");
                progressSeekBar.setProgress((int) pos);
            }
        }
        catch (Exception e) {
        }
    }

progressEnable をグローバルに宣言します。

private boolean progressEnable=true;
于 2012-07-10T09:19:18.363 に答える
1

私は通常、このコードを使用します:

private int mProgressStatus;
private Handler mHandler = new Handler();

public void startProgress(View view) {
    final ProgressBar progressBar = (ProgressBar) findViewById(R.id.horizontal_progress);
    mProgressStatus = 0;
    progressBar.setProgress(mProgressStatus);

    //progressBar.setVisibility(View.VISIBLE);
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(final Void... params) {
            while (mProgressStatus < 100) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                mProgressStatus += 15;
                mHandler.post(new Runnable() {
                    public void run() {
                        progressBar.setProgress(mProgressStatus);
                    }
                });
            }
            return null;
        }

    }.execute();
}

お役に立てれば

于 2016-10-18T11:07:20.527 に答える