Reputation: 43
Im trying to update a TextView
.
This method is located in my Main Class and it is called in onCreate()
;
I have tried using runOnUiThread()
to no avail..
As soon as the 30 seconds is reached and it tries to update the TextView it crashes!
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)
Upvotes: 3
Views: 5409
Reputation: 7905
Use a handler as stated by @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 Threadhandler.postDelayed(this, 30000);
will make it repeat every 30secsUpvotes: 1
Reputation: 135
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
because you edit textView3 in thread
try it :
public void updateDisplay() { Timer 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
}
Upvotes: 1
Reputation: 2734
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.
}
Upvotes: 2