[英]Android Dev: Run TimerTask in UI Thread
Im trying to update a TextView
.我正在尝试更新
TextView
。
This method is located in my Main Class and it is called in onCreate()
;此方法位于我的 Main Class 中,并在
onCreate()
中调用;
I have tried using runOnUiThread()
to no avail..我试过使用
runOnUiThread()
无济于事..
As soon as the 30 seconds is reached and it tries to update the TextView it crashes!一旦达到 30 秒并尝试更新 TextView,它就会崩溃!
Any help is appreciated:任何帮助表示赞赏:
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
}
And the error is:错误是:
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: Only the original thread that created a view hierarchy can touch its views. android.view.ViewRootImpl$CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能接触其视图。
because you edit textView3 in thread因为你在线程中编辑 textView3
try it:尝试一下:
public void updateDisplay() { Timer timer = new Timer(); 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
} }
Use a handler as stated by @Ezio使用@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()
will run the runnable on the UI Thread Looper.getMainLooper()
将在 UI 线程上运行 runnablehandler.postDelayed(this, 30000);
will make it repeat every 30secs
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.