簡體   English   中英

Android 開發:在 UI 線程中運行 TimerTask

[英]Android Dev: Run TimerTask in UI Thread

我正在嘗試更新TextView

此方法位於我的 Main Class 中,並在onCreate()中調用;

我試過使用runOnUiThread()無濟於事..

一旦達到 30 秒並嘗試更新 TextView,它就會崩潰!

任何幫助表示贊賞:

public void updateDisplay() {
    Timer timer = new Timer();


    timer.schedule(new TimerTask() {


                       public void run() {
                           Calendar c = Calendar.getInstance();
                           int mYear = c.get(Calendar.YEAR);
                           int mMonth = c.get(Calendar.MONTH);
                           int mDay = c.get(Calendar.DAY_OF_MONTH);
                           int mHour = c.get(Calendar.HOUR_OF_DAY);
                           int mMinute = c.get(Calendar.MINUTE);

                           textView3.setText(new StringBuilder()
                                   // Month is 0 based so add 1
                                   .append(mDay).append("/")
                                   .append(mMonth + 1).append("/")
                                   .append(mYear)
                                   .append(" - ")
                                   .append(mHour)
                                   .append(":")
                                   .append(mMinute));
                       }
                   }

            ,0,30000);//Update text every 30 seconds
}

錯誤是:

E/AndroidRuntime: FATAL EXCEPTION: Timer-0
              Process: ggrgroup.com.workforceapp, PID: 21879
              android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
                  at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7261)
                  at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1100)
                  at android.view.ViewGroup.invalidateChild(ViewGroup.java:5219)
                  at android.view.View.invalidateInternal(View.java:12900)
                  at android.view.View.invalidate(View.java:12860)
                  at android.view.View.invalidate(View.java:12844)
                  at android.widget.TextView.checkForRelayout(TextView.java:7459)
                  at android.widget.TextView.setText(TextView.java:4390)
                  at android.widget.TextView.setText(TextView.java:4247)
                  at android.widget.TextView.setText(TextView.java:4222)
                  at ggrgroup.com.workforceapp.MainActivity$1.run(MainActivity.java:77)
                  at java.util.Timer$TimerImpl.run(Timer.java:284)
    public void updateDisplay() {   
      Timer timer = new Timer();
      timer.schedule(new TimerTask() {

    @Override
    public void run() {
        // Your logic here...

        // When you need to modify a UI element, do so on the UI thread. 
        // 'getActivity()' is required as this is being ran from a Fragment.
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // This code will always run on the UI thread, therefore is safe to modify UI elements.
                myTextBox.setText("my text");
            }
        });
    }
}, 0, 30000); // End of your timer code.   

 }

android.view.ViewRootImpl$CalledFromWrongThreadException:只有創建視圖層次結構的原始線程才能接觸其視圖。

因為你在線程中編輯 textView3

嘗試一下:

public void updateDisplay() { 計時器 timer = new Timer();

timer.schedule(new TimerTask(){


    public void run() {

        runOnUiThread(new Runnable(){
            @Override
            public void run() {
                Calendar c = Calendar.getInstance();
                int mYear = c.get(Calendar.YEAR);
                int mMonth = c.get(Calendar.MONTH);
                int mDay = c.get(Calendar.DAY_OF_MONTH);
                int mHour = c.get(Calendar.HOUR_OF_DAY);
                int mMinute = c.get(Calendar.MINUTE);

                textView3.setText(new StringBuilder()
                    // Month is 0 based so add 1
                    .append(mDay).append("/")
                    .append(mMonth + 1).append("/")
                    .append(mYear)
                    .append(" - ")
                    .append(mHour)
                    .append(":")
                    .append(mMinute));
            }
        });

    }
}

, 0, 30000);//Update text every 30 seconds

}

使用@Ezio 所述的處理程序

Handler handler = new Handler(Looper.getMainLooper());
    
Runnable runnable = new Runnable() {

    public void run() {
        Calendar c = Calendar.getInstance();
        int mYear = c.get(Calendar.YEAR);
        int mMonth = c.get(Calendar.MONTH);
        int mDay = c.get(Calendar.DAY_OF_MONTH);
        int mHour = c.get(Calendar.HOUR_OF_DAY);
        int mMinute = c.get(Calendar.MINUTE);

        textView3.setText(new StringBuilder()
            // Month is 0 based so add 1
            .append(mDay).append("/")
            .append(mMonth + 1).append("/")
            .append(mYear)
            .append(" - ")
            .append(mHour)
            .append(":")
            .append(mMinute));

        //repeat every 30secs
        handler.postDelayed(this, 30000);
    }
}

handler.postDelayed(runnable, 30000);
  • Looper.getMainLooper()將在 UI 線程上運行 runnable
  • handler.postDelayed(this, 30000); 將使其每 30 秒重復一次

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM