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

您正在while (progressBar.getProgress() < 100)UI 线程中运行 a (您使用runOnUiThread),因此 UI 线程将被阻塞(并且没有绘制),直到此循环完成。

你可以:

  • runOnUiThread里面的循环,也许,一个睡眠里面的runOnUiThread电话。但是,它不是首选的解决方案,因为您使用过多的 CPU 来查找值更改。sleep 方法有点难看,但解决了 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 回答
1

您可以使用 RXJava 自动前进进度条。

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    if (autoProgress) {
        autoProgressSubscriber = Observable.interval(0, 1000/60, TimeUnit.MILLISECONDS) //~60fps
                    .map(index -> calculateAutoProgress())
                    .subscribe(progress -> {
                        if (progressBar != null) {
                            progressBar.setProgress(progress);
                        }
                    });
    }
}

@Override
protected void onDetachedFromWindow() {
    if (autoProgress) {
        autoProgressSubscriber.unsubscribe();
    }
    super.onDetachedFromWindow();
}
于 2017-02-03T17:24:40.627 回答