0

TimerTask から UI を変更しようとしましたが、TimerTask はバックグラウンド スレッドで実行され、バックグラウンド スレッドは UI を変更できないため、それは不可能であることがわかりました。
ここで私の質問は次のとおりです。ProgressBar と TextView を TimerTask から変更していましたが、ProgressBar では機能しましたが、TextView では機能しませんでした。ProgressBar を変更できるのはなぜですか?

これで ProgressBar に問題がないのはなぜですか?

timer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            int time = playerTimer(time);

            progressbar.setProgress(time);
            playerTime.setText(time);

        }

    }, 0, 1000);
4

4 に答える 4

2

その理由refreshProgress(int id, int progress, boolean fromUser)は、ソース コードでメソッドProgressBar.javaを見ると、プログレス バーが UI スレッドである現在のスレッド自体の内部で更新されていることがわかるからです。UI スレッドでない場合、プログレス バーは Runnable を使用して更新されます。

また、非UIスレッドからUIを一度更新したい場合は、使用できますrunOnUIThread(Runnable action)

于 2013-08-03T07:06:53.070 に答える
1

ProgressBarクラスはそれで動作するように設計されています。これを行うコードは次のとおりです。

  if (mUiThreadId == Thread.currentThread().getId()) {
        doRefreshProgress(id, progress, fromUser, true);
    } else {
        if (mRefreshProgressRunnable == null) {
            mRefreshProgressRunnable = new RefreshProgressRunnable();
        }

        final RefreshData rd = RefreshData.obtain(id, progress, fromUser);
        mRefreshData.add(rd);
        if (mAttached && !mRefreshIsPosted) {
            post(mRefreshProgressRunnable); //--posted to view's thread --
            mRefreshIsPosted = true;
        }
    }

これは、UI スレッドにいるかどうかを確認しています。そうでない場合は、UI スレッドにランナブルを投稿します。私の推測では、この設計により、progressBar を複数の場所から更新することができます。

他のビューについては、次のことを行う必要があります。

runonUiThread(new Runnable(){

 @Override
 public void run(){
   //--- change the view--
 }

});
于 2013-08-03T07:18:17.997 に答える
1

すべての UI 操作をメイン スレッドで行う必要があるわけではありません。別のスレッドから呼び出すことができるものは、メイン スレッドでビューまたはビュー ツリーのレイアウトおよび/または描画をスケジュールします。実際には、どのメソッドが非 UI スレッドから安全に呼び出され、どのメソッドがそうでないかを識別しようとするのは、実際には良い考えではありません。

これを回避AsyncTaskするには、UI スレッドで実行されるコールバック内からすべての UI 操作を使用および実行する必要があります: onPreExecute()onPostExecute()、およびonProgressUpdate()

于 2013-08-03T07:04:56.330 に答える
1

メソッドが同期されているためsetProgress、別のスレッドから呼び出されるように設計されているようです。ただし、ドキュメントにはそれが明確に記載されていません。

于 2013-08-03T07:07:18.513 に答える