I do not understand the behaviour of my code. To summarize, I have an editText (variable hours in my code) that start with "00". I am creating a thread which prevents this editText to not have 2 digit. Let s assume that this editText cannot have more than 2 digits. What I am doing is that I create a thread. In this thread, whenever this editText does not have 2 digits(so 1 digit), I add to it a "0".
However, whenever I just put one digit on the editText, it is getting crazy and go into an infinite loop and other stuff that I don't understand. Here is my code:
Thread digitLessThanTwoThread;
EditText hours = (EditText) findViewById(R.id.hours);
digitLessThanTwoThread= new Thread(){
@Override
public void run()
{
while(true) {
if (hours.getText().toString().length() != 2 && !hours.isFocused()) {
main_activity.runOnUiThread(new Runnable() {
@Override
public void run() {
hours.setText("0" + hours.getText().toString());
}
});
}
}
}
};
digitLessThanTwoThread.start();
Moreover, at the end, The editText hours displayed "00". I also get a message "suspending all threads took: XXX seconds" before doing anything actually!
There are two problems here. First, the simple one:
while(true)
This will run the thread at full power until as you seem to be noticing, the OS steps in to stop the runaway thread. You should instead add an addTextChangedListener()
listener, for example.
The more complex one is:
main_activity.runOnUiThread(new Runnable() {
@Override
public void run() {
hours.setText("0" + hours.getText().toString());
}
});
I think you are assuming that this is executed synchronously, that is the setText()
is executed before runOnUiThread()
returns. However, it is asynchronous, so next time round the loop your if
is still true, and you queue another action on the UI thread to set the text and so on, so the UI thread may never get a chance to run until the OS steps in to halt the runaway thread.