I have one thread class which star in onCreate of an activity.
class MyThread extends Thread
{
void run()
{
//My code which takes time.
}
}
//-------------------------- To run the thread
MyThread mThread = new MyThread();
mThread.start();
On some external events i need to stop/destroy currently running thread.
And Then i create a new copy of MyThread and call start function on the new thread to run it.
But i am not able to destroy/stop the previous running thread.
Is there any API by which we can destroy running thread.
you cannot destroy...only the android will stop the thread when requires.. you cannot stop or destroy it.. instead try like this..
class MyThread extends Thread
{
void run()
{
while(bool){
//My code which takes time.
}
}
}
//-------------------------- To run the thread
MyThread mThread = new MyThread();
mThread.start();
now when u want to stop the thread... change bool value to false
bool=false;
now your code doesnt run... and you can start new thread...
The Thread.interrupt() method is the accepted way of stopping a running thread, but some implementation details are on you: if your thread is doing IO (or anything else that can throw InterruptedException), it's your responsibility to make sure that you close any resources you have open before you stop your thread.
This page indicates why some of the thread functionality present in earlier versions of Java was deprecated, and why Thread.destroy() was never actually implemented.
You can use AsyncTask insted of Thread, because its known as Painless Threading in android. Once you implement you don't need to bother about Thread Management.
AsyncTask can easily handle and it's very easy for handling ui.
Instead of using Thread.interrupt() or any other methods that can throw an exception, you can implement your own stopThread method. In order to do that, you must have a local boolean variable with the name " keepRunning " for example.
If you have a for loop or a while loop inside your working code that takes time, you can check for the boolean, if it's false you break the loop and your code won't be running anymore.
class MyThread extends Thread
{
boolean keepRunning = true;
void run()
{
//inside your for loop
if (keepRunning) {
//keep running code which takes time.
}
else break;
}
void stopThread() {
keepRunning = false;
}
}
//To run the thread
MyThread mThread = new MyThread();
mThread.start();
//To stop the thread
mThread.stopThread();
After stopping the thread, you can initialize it again to mThread.
Try something like this..
class MyThread extends Thread
{
void run()
{
//My code which takes time.
}
}
//-------------------------- To run the thread
MyThread mThread = new MyThread();
mThread.start();
// PERFORM ALL YOUR OPERATIONS HERE..
mThread.destroy();
Related
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)
I want perform a network call in every 30sec to push some metrics to Server. Currently I am doing it using thread.sleep(). I found some articles saying thread.sleep() has some drawbacks. I need to know am I doing it right? or Replacing the thread with Handler will improve my code?
public static void startSending(final Context con) {
if (running) return;
running = true;
threadToSendUXMetrics = new Thread(new Runnable() {
#Override
public void run() {
do {
try {
Thread.sleep(AugmedixConstants.glassLogsPushInterval);
} catch (InterruptedException e) {
mLogger.error(interrupt_exception + e.getMessage());
}
// to do to send each time, should have some sleep code
if (AugmedixConstants.WEBAPP_URL.equals(AugmedixConstants.EMPTY_STRING)||!StatsNetworkChecker.checkIsConnected(con)) {
Utility.populateNetworkStat();
mLogger.error(may_be_provider_not_login_yet);
} else
sendUXMetrics();
} while (running);
if (!uxMetricsQueue.isEmpty()) sendUXMetrics();
}
});
threadToSendUXMetrics.start();
}
If You are using only one thread in the network, then usage of the thread.sleep() is fine. If there are multiple threads in synchronization, then the thread.sleep() command will block all the other threads that are currently running.
As per the details you've provided, there is only one thread present which isn't blocking any other active threads which are running in synchronization, so using thread.sleep() shouldn't be a problem.
Use Handler.postDelayed to schedule tasks if you are working in UI Thread and Thread.sleep if you are working in background thread.
Apparently you are sending some data using network, you must do it in the background thread, hence Thread.sleep is recommended.
Simple is:
Thread.sleep(millisSeconds): With this method, you only can call in background tasks, for example in AsyncTask::doInBackground(), you can call to delay actions after that. RECOMMENDED CALL THIS METHOD IN BACKGROUND THREAD.
Handler().postDelayed({METHOD}, millisSeconds): With this instance, METHOD will trigged after millisSeconds declared.
But, to easy handle life cycle of Handler(), you need to declare a Handler() instance, with a Runnable instance. For example, when your Activity has paused or you just no need call that method again, you can remove callback from Handler(). Below is example:
public class MainActivity extends Activity {
private Handler mHandler = Handler();
public void onStart(...) {
super.onStart(...)
this.mHandler.postDelayed(this.foo, 1000)
}
public void onPaused(...) {
this.mHandler.removeCallback(this.foo)
super.onPaused(...)
}
private Runnable foo = new Runnable() {
#Override
public void run() {
// your code will call after 1 second when activity start
// end remove callback when activity paused
// continue call...
mHandler.postDelayed(foo, 1000)
}
}
}
The code above just for reference, I type by hand because don't have IDE to write then copy paste.
I'm curious whether or not it's possible to call a network process from the UI thread if the method called is in an instance of a Threaded class... pseudo...
class MyNetworkClass extends Thread{
public boolean keepGoing = true;
public void run(){
while(keepGoing);
}
public void doSomeNetworkStuff(){
//do things that are illegal on the UI Thread
}
}
//and then in my Activity...
MyNetworkClass mnc = new MyNetworkClass();
mnc.start();
mnc.doSomeNetworkStuff();
This feels totally illegal to me, but I'm wondering if it is in fact, and if so why?
You actually called the mnc.doSomeNetworkStuff() method from the same thread as mnc.start();.
This is presumably the UI thread, but for sure not the thread which just started with mnc.start;
Consider the situation:
//creates thread object - does not start a new thread yet
Thread thread = new Thread() {
public void run() {}
};
//...
thread.start(); //this actually started the thread
// the `run` method is now executed in this thread.
//However if you called `run` manually as below
thread.run();
// it would be executed in the thread from which you have called it
// assuming that this flow is running in the UI thread, calling `thread.run()`
// manually as above makes it execute in the UI thread.
EDIT:
Just to make things more clear. Consider that you have some static utility class like below:
public static class SomeUtilityClass {
public static void someUtilityMethod(int i) {
Log.i("SomeUtilityClass", "someUtilityMethod: " + i);
}
}
Then somewhere in your code, called from your "main" thread:
new Thread() {
#Override
public void run() {
// 1.
// call the utility method in new thread
SomeUtilityClass.someUtilityMethod(1);
}
}.start();
// 2.
// call the same method from "main" thread
SomeUtilityClass.someUtilityMethod(2);
Notice that Thread#start() exits immediately and you are not guaranteed which call to SomeUtilityClass.someUtilityMethod(); will be executed first.
I just need to stop a thread which was created in previous run time of the same application. This is the scenario. I'm retrieving data from database for the notification using thread in background, But when I start that application again, number of threads are increasing. I need to stop this. I think its better to stop the background running thread in onCreate() method of the application's main class. But noway to do it. Please help me on this thing as soon as possible.
Thanks and Best Regards,
Shehan.
Keep a static reference to the running Thread in your activity class. Inside your thread you need to have a boolean variable you can set or a method you can call that will cause your thread to complete. In onCreate() you can check if you have a running thread, and if so, tell it to stop. Here's a code example:
In your activity:
private static Thread myThread;
In your activity, when you create the thread:
if (myThread != null) {
if (myThread.isAlive()) {
myThread.running = false; // Tell the thread to stop running now
}
}
myThread = new Thread(...);
myThread.start();
In your thread:
public boolean running = true; // Initator of this thread should set this to false to make the thread complete
public void run() {
while (running) {
// do whatever your thread does in a loop
}
}
You can stop the ruuning threads onDestroy() of activity.
please find the below eg:
static boolean stopThread=false;
public myThread implements Ruunable{
public void run(){
while(true){
//your logic
if(stopThread)
break;
}
}
#Override
protected void onDestroy()
{
stopThread=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?