I have this thread:
myThread = new Thread(new Runnable() {
public void run() {
ServerSocket ss = null;
while (!end) {
final String incomingMsg;
try {
ss = new ServerSocket(2201);
ss.setSoTimeout(15000);
.. some code ...
}
});
myThread.start();
Now i need to stop this with button but nothing work, and i have tried with some code like:
Handler handler= new Handler();
handler.removeCallbacks(myThread);
myThread.interrupt();
But Thread not stopping =(
You can't. Android will automatically stops thread when needed.
What you can do is just stop executing the code inside run() method, Using boolean or something
The accepted answer is not correct. Android does nothing to manage the threads you start, however you start them.
Technically speaking, threads cannot be "stopped". They can interrupted. Interrupting a thread just means that a flag is set, which you, in your thread's implementation, need to consider and exit from the run() method. For example,
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// Do stuff
}
}
});
Then you can call t.interrupt() later on to "stop" your thread.
If you ignore the interrupted flag in your thread's implementation, your thread will never stop. For example, if you replaced // Do stuff above with SystemClock.sleep(Integer.MAX_VALUE) the thread will never exit, regardless of it being interrupted.
Many IO operations implemented in the SDK also pay attention to the interrupted flag, which is why you can interrupt a thread that's participating in blocking IO. See InterruptedException.
You can use .stop(), but it is very bad practice and it can cause you some troubles. Try to add some boolean inside your .run() (like Wizard said)
Related
I've got this code to schedule a task every so often:
final Handler handler = new Handler();
Runnable update = new Runnable() {
#Override
public void run() {
try{
runOnUiThread(new Runnable(){
public void run(){
lbl.setText(info);
cpb.setProgress(Float.valueOf(textInfo);
}
});
handler.postDelayed(this, 1000);
}
catch (Exception e) {
// TODO: handle exception
}
}
};
I want to constantly update the UI (every second, etc). The code works, however, the interface starts lagging. After the code iterates the task a few times the interface stops responding.
Is there any way I can schedule a task to repeat periodically without overloading the memory and without the interface lagging.
Assuming lbl is a TextView and cpb is a ProgressBar, your code will not considerably lag any device as it is. The problem lies somewhere else. Also, you appear to have missed a closing bracket on (Float.valueOf(textInfo);.
As an aside, you are unnecessarily using runOnUiThread inside the Runnable from what I can see. When you create a new Handler() it is implicitly linked to the calling thread's Looper, which I am assuming is the UI thread. In which case, the update Runnable will already be running on the UI thread. EDIT: This should not be the cause of the lag for the record, since iirc runOnUiThread checks if it is being executed on the UI thread then just runs it immediately, without doing another post.
I'm recently getting involved in some concurrent programming specially with Java and Android.
I have some questions regarding Handlers.
1 - It is known that we need to associate a Handler with a thread, and it will run on the thread it was invoked on. However, in some examples on SO, the user is doing
public class MainActivity extends Activity
{
private Handler handler = new Handler();
#Override
public void onCreate(Bundle savedInstanceState)
{
handler.postDelayed(runnable, 1000);
}
private Runnable runnable = new Runnable()
{
public void run()
{
//Do whatever
handler.postDelayed(this, 30000);
}
};
In this example, I assume we are doing the Handler thing on the UI Thread, RIGHT ?
Can I do a network operation here in place of //DO Whatever ? I don't think so, because we are on the main thread.
Is doing this pointless ? As one may use AsyncTask to replace this task ?
How can I apply this same example but not on the UI thread, rather a seperate thread ?
Do thread or Runnables have something similar to post delayed ?
Is it common to use the handler just for its postdelayed feature and not the main task handlers are made for, ie, being the middle man between the thread and the UI/Activity ?
Handlers are useful only when you want update UI. As you may know we cannot update UI from non UI Thread. If you are going to do some network stuff in background thread, and then update UI, you have to use Handler class or AsyncTask or you can do like this:
(from non UI Thread)
SomeView.post(new Runnable() {
//updating UI
});
If whatever you are doing is "heavy" you should be doing it in a Thread. If you do not explicitly start it in its own thread, then it will run on the main (UI) thread which may be noticeable as jittery or slow to respond interface by your users.
Interestingly when you are using a thread it is often useful to also use a Handler as a means of communication between the work thread that you are starting and the main thread.
A typical Thread/Handler interaction might look something like this:
Handler h = new Handler(){
#Override
public void handleMessage(Message msg){
if(msg.what == 0){
updateUI();
}else{
showErrorDialog();
}
}};
Thread t = new Thread() {
#Override
public void run(){
doSomeWork();
if(succeed){
//we can't update the UI from here so we'll signal our handler and it will do it for us.
h.sendEmptyMessage(0);
}else{
h.sendEmptyMessage(1);
}
} };
In general though, the take home is that you should use a Thread any time you are doing some work that could be long running or very intensive (i.e. anything network, file IO, heavy arithmatic, etc).
I'm wondering when should I use handler.post(runnable); and when should I use
new Thread(runnable).start();
It is mentioned in developers documentation for Handler:
Causes the Runnable r to be added to the message queue. The runnable
will be run on the thread to which this handler is attached.
Does this mean if I write in the onCreate() of Activity class:
Handler handler = new Handler();
handler.post(runnable);
then runnable will be called in a separate thread or in the Activity's thread?
You should use Handler.post() whenever you want to do operations on the UI thread.
So let's say you want to change a TextView's text in the callback. Because the callback is not running on the UI thread, you should use Handler.post().
In Android, as in many other UI frameworks, UI elements (widgets) can be only modified from UI thread.
Also note that the terms "UI thread" and "main thread" are often used interchangeably.
Edit: an example of the long-running task:
mHandler = new Handler();
new Thread(new Runnable() {
#Override
public void run () {
// Perform long-running task here
// (like audio buffering).
// You may want to update a progress
// bar every second, so use a handler:
mHandler.post(new Runnable() {
#Override
public void run () {
// make operation on the UI - for example
// on a progress bar.
}
});
}
}).start();
Of course, if the task you want to perform is really long and there is a risk that user might switch to some another app in the meantime, you should consider using a Service.
To answer you specific question:
Does this mean if in the onCreate of Activity class I write:
Handler handler = new Handler() hanlder.post(runnable); then, runnable
will be called in a separate thread or on the Activity's thread?
No it won't be. The Runnable will be called on the Main Thread itself.
Handler is simply used for posting a message to the thread to which it is attached (where its is created).
It does not create a thread on its own.
In your example, you created a Handler in the main Thread (that where Activity.OnCreate() is called) and hence any message posted on such a Handler will be run on the Main Thread only.
Example is jacked:
mHandler = new Handler();
new Thread(new Runnable(){
#Override
public void run () {
mHandler.post(new Runnable() {
#Override
public void run () {
mUiView.setX(x);
}
});
}
}).start();
Alternatively you can skip the handler and use the post method on the view directly:
new Thread(new Runnable(){
#Override
public void run () {
mUiView.post(new Runnable() {
#Override
public void run () {
mUiView.setX(x);
}
});
}
}).start();
This is a good post that outlines the difference: What exactly does the post method do?
use handler.post() when you want to post the code (usually from background thread) to the main thread. Yea, POST,just like you, post a letter to someone. With the help of handler the code will be executed ASAP i.e. almost immediately.
I am using the following code to access a url:
final Handler handler = new Handler();
Runnable runnable = new Runnable()
{
public void run()
{
img.setImageBitmap(returnBitmap("fromurl"));
handler.postDelayed(this, 50);
}
};
handler.postDelayed(runnable, 2000);
I observed that if the server is not up the app takes ages to close correctly if I hit the back button. Is there anyway way I could speed up the exit procedure.
Runnables will exit automatically when finished with their run() method. If you are employing a loop to do some work, the solution that Jay Ho suggested will help exit from the loop cleanly. If you want to prevent the Handler from executing the runnable (before it posts) you can use handler.removeCallbacksAndMessages(null)1 to clear the queue. Placing it in onDestroy() is your best bet. Otherwise, you're on your own. Once you've spawned a thread, you're at the mercy of the Android operating system to terminate it once its done.
Side note: I've run into problems like this before, and it's usually a call to a system service or the implementation of a Broadcast Listener or Alarm that mucks up the exit process.
private Runnable runnable = new Runnable() {
private boolean killMe=false;
public void run() {
//some work
if(!killMe) {
img.setImageBitmap(returnBitmap("fromurl"));
handler.postDelayed(this, 50);
}
}
public void kill(){
killMe=true;
}
};
ThreadPoolExecutor threadPoolExecutor = Executors.newSingleThreadExecutor();
Runnable longRunningTask = new Runnable();
// submit task to threadpool:
Future longRunningTaskFurure = threadPoolExecutor.submit(longRunningTask);
... ...
// At some point in the future, if you want to kill the task:
longRunningTaskFuture.cancel(true);
... ...
I have one function which queries a network server with a few "ping pongs" back and forth, and have written a custom handler to handle the message communication between my main UI thread and the communication thread (I was using AsyncTask for this, but as the program got more complex, I have decided to remove the communication code to its own class outside of the main activity).
Triggering a single instance of this thread communication from onCreate works perfectly, no problem.
I want this query to run on a regular timed basis -- in the background -- for the entire time the app is in use, so I've set up another thread called pollTimer, which I'm trying to use to call the OTHER thread at a regularly scheduled basis.
Obviously, it's crashing, or I wouldn't be posting this.
Is there a way to get a thread within a thread? Or put differently, trigger a thread from another thread?
Timer pollTimer = new Timer();
private void startPollTimer(){
pollTimer.scheduleAtFixedRate(new TimerTask(){
public void run(){
Log.d(TAG,"timer dinged");
//if the following is commented out, this "dings" every 6 seconds.
//if its not commented out, it crashes
threadedPoll();
}
}, 3120, 6000);
}
private void threadedPoll() {
testThread(asciiQueries,WorkerThreadRunnable.typeLogin);
}
edit: it would probably help to include the "testThread" function, which works by itself when called from onCreate, but does not make it when called from the Timer.
"WorkerThreadRunnable" is the massive chunk of code in its own class that has replaced the mess of having AsyncTask handle it inside the main activity.
private Handler runStatHandler = null;
Thread workerThread = null;
private void testThread(String[] threadCommands, int commandType){
if(runStatHandler == null){
runStatHandler = new ReportStatusHandler(this);
if(commandType == WorkerThreadRunnable.typeLogin){
workerThread = new Thread(new WorkerThreadRunnable(runStatHandler,threadCommands, WorkerThreadRunnable.typeLogin));
}
workerThread.start();
return;
}
//thread is already there
if(workerThread.getState() != Thread.State.TERMINATED){
Log.d(TAG,"thread is new or alive, but not terminated");
}else{
Log.d(TAG, "thread is likely deaad, starting now");
//there's no way to resurrect a dead thread
workerThread = new Thread(new WorkerThreadRunnable(runStatHandler));
workerThread.start();
}
}
You seem to be well on the way already - the nice thing about handlers, though, is that they aren't limited to the UI thread - so if you have a Handler declared by one thread, you can set it up to take asynchronous instructions from another thread
mWorkerThread = new WorkerThread()
private class WorkerThread extends Thread {
private Handler mHandler;
#Override
public void run() {
mHandler = new Handler(); // we do this here to ensure that
// the handler runs on this thread
}
public void doStuff() {
mHandler.post(new Runnable() {
#Override
public void run() {
// do stuff asynchronously
}
}
}
}
Hopefully that helps... if I'm totally off base on your problem let me know
Wots wrong with a sleep() loop? Why do you have pagefuls of complex, dodgy code when you could just loop in one thread?