This question already has answers here:
Setting text on TextView from background thread anomaly
(2 answers)
Closed 3 years ago.
I don't know why non UI thread can update the text view in while loop like this:
Runnable timeCount = new Runnable() {
#Override
public void run() {
int i = 0;
while (true)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mTextView.setText(i++ + "");
}
}
};
Thread thread = new Thread(timeCount);
thread.start();
has been called after Activity Resume.
Please help to explain about this!
the ViewRoot will call the checkThread() to check if it's the main thread ,if your thread be called just before the method of checkThread() .it will not to throw the error。
As mentioned in documentation(https://developer.android.com/topic/performance/threads.html#references) Android UI classes are not thread safe.
If you try to update View objects from any other thread than the one created it you may face anomaly. Sometimes it may seem to work however there are no guarantees.
Related
This question already has answers here:
javafx animation looping
(3 answers)
Closed 5 years ago.
I am trying to build a clock in javafx but the GUI crashes when I try using an infinite loop.
while (true) {
Date time = new Date();
// mins and hour are labels
if (time.getMinutes() < 10) {
mins.setText("0" + Integer.toString(time.getMinutes()));
} else {
mins.setText(Integer.toString(time.getMinutes()));
}
if (time.getHours() < 10) {
hour.setText(0 + Integer.toString(time.getHours()));
} else {
hour.setText(Integer.toString(time.getHours()));
}
}
I heard I can use something called a thread but I didn't really understand how to properly implement it.
Looks like you are using an infinite loop in the UI thread. You should keep track of time in a background thread, but update the UI in UI thread.
To run in background thread, use:
new Thread(new Runnable(){
public void run(){
//your code here.
}
}).start();
To run in UI thread, use:
Platform.runLater(new Runnable(){
public void run(){
//your code here.
}
});
That is perfectly reasonable. Never block the main thread! Use an additional thread in order to achieve your goal.
Task<Void> workingTask = new Task<Void>() {
#Override
public Void call() {
while (true) {
//yourcode
}
}
and use Platform.runLater(()-> { //yourcode}); in order to send small tasks to main javafx thread. For e.g.
Platform.runLater(() -> {
mins.setText(Integer.toString(time.getMinutes()));
});
This question already has answers here:
Thread.interrupt () doesn't work
(2 answers)
Closed 6 years ago.
onIncomingCall() is a overridden method from a class in third party library pjsip. This method is called when an incoming call is made using SIP. Somehow this method makes it possible for the call to be answered ONLY if the Call answering code be inside the same method or called within the same method. But I want the call to be answered when the user presses the button. I have created a call back and make the user press the button when the call comes but the call answering code is not working if its called outside of onIncomingCall() method. So I decided to put Thread.sleep(10000) in onIncomingCall() and when the user presses the button I would like to cancel this thread so that the call answering code can be executed.
I used Thread.currentThread().interrupt() but the Thread.sleep is not cancelled at all. I wrote a separate activity to test this functionality but it failed, meaning Thread.currentThread.interrupt is not working in for me at all. What is the best option to achieve this? Kindly please update me .. I am really struggling with this.
#Override
public void onIncomingCall(OnIncomingCallParam prm) {
onIncomingCallParam = prm;
try {
Thread.sleep(10000);
} catch(InterruptedException ie) {
ie.printStackTrace();
}
answerCall();
}
UPDATE:
I fixed the issue with the below approach
resetThread();
while (testThread) {
try {
Log.d(TAG,"testThread true");
Thread.sleep(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
Log.d(TAG,"Call Answering code");
private void resetThread() {
Thread newThread = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(10000);
testThread = false;
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
});
try {
newThread.start();
} catch (Exception ie) {
ie.printStackTrace();
}
}
The problem here is related to the fact that you don't interrupt the right Thread, if you call Thread.currentThread().interrupt(), you will interrupt the current thread not the one that it is currently sleeping.
Here is a clear example to show the main idea:
// Here is the thread that will only sleep until it will be interrupted
Thread t1 = new Thread(
() -> {
try {
Thread.sleep(10_000L);
System.err.println("The Thread has not been interrupted");
} catch (InterruptedException e) {
System.out.println("The Thread has been interrupted");
}
}
);
// Start the thread
t1.start();
// Make the current thread sleep for 1 sec
Thread.sleep(1_000L);
// Try to interrupt the sleeping thread with Thread.currentThread().interrupt()
System.out.println("Trying to call Thread.currentThread().interrupt()");
Thread.currentThread().interrupt();
// Reset the flag to be able to make the current thread sleep again
Thread.interrupted();
// Make the current thread sleep for 1 sec
Thread.sleep(1_000L);
// Try to interrupt the sleeping thread with t1.interrupt()
System.out.println("Trying to call t1.interrupt()");
t1.interrupt();
Output:
Trying to call Thread.currentThread().interrupt()
Trying to call t1.interrupt()
The Thread has been interrupted
As you can see in the output, the thread is interrupted only when we call t1.interrupt(), in other words only when we interrupt the right Thread.
Maybe all calls has to be done on the same thread, which created library instance. Try using HandlerThread for posting it messages and handle those messages inside custom Handler instead of suspending thread.
This question already has answers here:
Why does an IllegalThreadStateException occur when Thread.start is called again
(7 answers)
Closed 8 years ago.
I have Thrad and Handler:
Handler handler = new Handler() {
#Override
public void handleMessage(android.os.Message msg) {
super.handleMessage(msg);
//do somethink
}
};
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
//do somethink
msg.obj = 1;
handler.sendMessage(msg);
thread.interrupt();
}
});
When app start, at first time thread.start(); all work fine.
But when I try start thread.start(); second time from button I have:
E/MessageQueue-JNI﹕ java.lang.IllegalThreadStateException: Thread already started.
You should check state of that thread before starting it.
if (thread.getState() == Thread.State.NEW)
{
thread.start();
}
Its not a good Idea to start a Thread more then once.
You have to check Whether a Thread is already started or not. if Thread not started yet
if(!thread.isAlive()){
thread.start();
}
The Better Idea is to Create new Thread instance.
At the end of run(), your thread dies. If you want to keep it alive, then add a blocking queue to the thread and make run() a big while loop that reads from the queue. Instead of calling start for each message, just add it to the queue instead.
Of course, you still have to call start() once (when your program initializes).
This question already has answers here:
How to start/stop/restart a thread in Java?
(9 answers)
Closed 7 years ago.
I have the following thread:
public void start() {
isRunning = true;
if (mainThread == null) {
mainThread = new Thread(this);
mainThread.setPriority(Thread.MAX_PRIORITY);
}
if (!mainThread.isAlive()) {
try {
mainThread.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
At some point I want to stop it's operation:
public void stop() {
isRunning = false;
System.gc();
}
When calling start() again the following exception is thrown:
java.lang.IllegalThreadStateException
Pointing the mainThread.start() line of code.
What is the best way to start/stop a thread? how can I make this thread reusable?
Thanks!
Once a thread stop you cannot restart it in Java, but of course you can create a new thread in Java to do your new job.
The user experience won't differ even if you create a new thread or restart the same thread(this you cannot do in Java).
You can read the website for API specification http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html
What you might be looking for is Interrupts. An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate.
To know more about interrupts read the Java tutorial guide http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
From your code slice it seems that you are using a Runnable class with a Thread attribute. Instead of using stop/start you might use suspend/resume below:
private boolean isPaused;
public void run() {
while (!isRunning) {
// do your stuff
while (isPaused) {
mainThread.wait();
}
}
}
public void suspend() {
isPaused = true;
}
public void resume() {
isPaused = false;
mainThread.notify();
}
I did not add the synchronized blocks to keep the code small, but you will need to add them.
This question already has answers here:
How to stop a java thread gracefully?
(6 answers)
Closed 9 years ago.
I create a thread in Java inside a button to print a simple message but I cannot stop it.
Thread a = new Thread();
a.start();
while(true){
try{
Thread.sleep(2000);
System.out.println("code");
}catch(Exception e){
}
}
when I click on it, itvstarts to print the code, but it seems to be blocked (the button). I would like to know. how can I stop the thread? And if I stop it, would be the button available again?.
I´m using netbeans 7.3, thanks.
while(true){
}
starts an infinite loop due to which all the other operations are blocked.
Remove that
Use interrupt(). Then handle the InterruptedException
The thread you are starting is not doing anything. It starts when you call a.start() and instantly terminates, because there is no code for this thread to run. Following this, the same thread that started the new one, and that is processing the click event, enters an infinite loop, so your user interface is completely blocked.
You need to give some code for the new thread to execute. To do so, you either pass the thread a Runnable or you override the thread's run() method. For example, to give it a Runnable containing the loop that prints every 2 seconds, you could do:
final Thread a = new Thread(new Runnable() {
#Override public void run() {
while (true) {
try {
Thread.sleep(2000);
System.out.println("code");
} catch (InterruptedException e) {
break;
}
}
}
};
a.start();
After that, if you ever want to stop that thread, you'd need to save a reference to the thread a in a field or something, and then call a.interrupt(). This will cause sleep to throw an InterruptedException, which will be caught and will execute break, which terminates the infinite loop and allows the thread to reach the end of the run method, which terminates the thread.
For example:
private Thread a = null;
... click handler on start button ... {
if (a == null) {
a = new Thread(new Runnable() {
#Override public void run() {
while (true) {
try {
Thread.sleep(2000);
System.out.println("code");
} catch (InterruptedException e) {
break;
}
}
}
};
a.start();
}
}
... click handler on "stop" button ... {
if (a != null) {
a.interrupt();
a = null;
}
}
You do not stop a thread in Java, you send an interrupt() signal.
The Thread may, or may no catch the signal. If it is waiting, or sleeping or joining (wait(), sleep() or join()) has been called on it), an InterruptedException will be raised.
The Thread (in its while loop) can test whether it has been interrupted by calling the isInterrupted() method and then decide to commit suicide (e.g. exit the loop).