I cant figure it out.
For what ever reason, this thread's code is actually running on the UI thread.
If i break point it the UI stops. or Sleep it, UI stopped. and hence network activity is unallowed as its on the "ui" thread.
Ive not used Async task, because I am unaware of the proper way of looping it. (calling a new instance of it in onPostExecute seems like bad practice, and as if async is for one off tasks.
I extend Thread.
public class SyncManager extends Thread {
public SyncManager(Context context){
sdb = new SyncManagerDBHelper(context);
mContext = context;
}
#Override
public void run() {
while(State == RUNNING) {
try{
SyncRecords(); // Break point here = UI freeze.
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(10000); // So also causes UI freeze.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void startThread() {
Log.i("SyncManager", "start called");
if((State == PAUSED || State == STOPPED) && !this.isAlive() )
{
State = RUNNING;
run();
}
}
ANd from my Activity I call
sm = new SyncManager(this);
sm.startThread();
You should use Thread.start() to start any new thread.
As far as I know calling run() directly will not cause the system to actually launch a new thread, hence your blocking UI.
Change your startThread() method to the following and it should then work:
public class SyncManager extends Thread {
public void startThread() {
if((State == PAUSED || State == STOPPED) && !this.isAlive()) {
State = RUNNING;
start(); // use start() instead of run()
}
}
}
Read here for more specific information from the Java revisited blog.
Related
I implemented this class in my android code
I made the below change in the run method(replaced "true"):
#Override
public void run() {
while (!isInterrupted()) {
try {
// A blocking operation. Initiate a ChatManager instance when
// there is a new connection
pool.execute(new ChatManager(socket.accept(), handler));
Log.d(TAG, "Launching the I/O handler");
} catch (IOException e) {
try {
if (socket != null && !socket.isClosed())
socket.close();
} catch (IOException ioe) {
}
e.printStackTrace();
pool.shutdownNow();
break;
}
}
}
I want to stop this thread before I close the app. So I implemented threadName.interrupt(); method. But this doesn't interrupt the thread.
I am actually confused with the usage of thread pool executor. So I am not sure how to do this efficiently. How can I implement interrupting this thread? When interrupt method is called, I want to close the socket, shutdown the pool and stop the thread.
Thread thread = new Thread () {
boolean isRunning = true;
public void stopThread() {
isRunning = false;
}
#Override
public void run() {
while (isRunning) {
try {
// A blocking operation. Initiate a ChatManager instance when
// there is a new connection
pool.execute(new ChatManager(socket.accept(), handler));
Log.d(TAG, "Launching the I/O handler");
} catch (IOException e) {
try {
if (socket != null && !socket.isClosed())
socket.close();
} catch (IOException ioe) {
}
e.printStackTrace();
pool.shutdownNow();
break;
}
}
}
};
thread.start();
Try this code. and call thread.stopThread() whenever you want the thread to stop.
if you want close an Android thread, you can set a variable to control run(),because run() is end, the thread will be closed.
The code is something like:
final boolean istrue=true;
new Thread(new Runnable() {
#Override
public void run() {
while (istrue){
//TODO your work
}
}
}).start();
}
If you want to close the thread, you only set istrue=false
Just call shutDownNow to close the pool and try interrupt all the threads inside it. You can check the difference in this post:
shutdown() will just tell the executor service that it can't accept new tasks, but the already submitted tasks continue to run
shutdownNow() will do the same AND will try to cancel the already submitted tasks by interrupting the relevant threads. Note that if
your tasks ignore the interruption, shutdownNow will behave exactly
the same way as shutdown.
If you want to interrupt or cancel an specific thread. I suggest you to use submit with Callables, With this, you will me able to work with your Future object, then if want to cancel a task you've given an executor service, you can call cancel(true) on its associated Future. When your task detects an interrupt request, it should preserve the interrupted status by calling Thread.currentThread().interrupt().
I need to destroy a thread before application suspend. This is my code:
public class MyThread extends Thread
{
public boolean mRun = false;;
#Override
public void run()
{
while (mRun)
{
.....
}
}
}
Activity:
#Override
public void onPause() {
if (mThread != null)
{
mThread.mRun = false;
try { mThread.join(); }
catch (InterruptedException e) { }
}
super.onPause();
}
But i'm pretty sure that the android system do not wait my thread conclusion and pause my application before it. How can i force thread conclusion?
This is the way, I used in my code meet your requirement.Hope, this will be helping you too. If you find a better solution, Please share it.
In the below snippet, mThread is thread got created in onCreate. OnDestroy is a method that would be called before your activity destroyed.Its a best place to empty the allocated resources.
#Override
public void onDestroy() {
super.onDestroy();
if(null != mThread) {
Thread dummyThread = mThread;
mThread = null;
dummyThread.interrupt(); // Post an interrupt request to this thread.
}
}
Cheers !
Are you sure that you are not getting an InterruptedException?
Try putting a stacktrace in the catch sentence...and also check if your thread isAlive().
You cannot do that. Thread.join is a blocking potentially long operation that must not be done on the UI Thread (onPause being on the UI Thread).
You can ask your thread to stop, (setting mRun to false is a commonly accepted way of doing so), but you cannot exclicitely wait on it.
To be sure , mark the thread as daemon, always check a flag if doing a repetitive task in a thread, like in a loop. Also, call interrupt, which will take care of blocking IO or network calls.
myThread.setDaemon(true)
and
cancelFlag = true;
myThread.interrupt();
So activity starts and I create a Thread which checks when to go to the next activity. But sometimes I need this activity to kill itself. onPause does this, but after that Thread is still alive and after time runs out it start a new activity. Is it possible to kill this Thread and stop goToFinals intent?
public class Questions extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String in = getIntent().getStringExtra("time");
long tmp = Long.parseLong(in);
endTime = (long) System.currentTimeMillis() + tmp;
Thread progress = new Thread(new Runnable() {
public void run() {
while(endTime > System.currentTimeMillis()) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Intent goToFinals = new Intent(Questions.this,End.class);
startActivity(goToFinals);
}
});
progress.start();
}
#Override
protected void onPause() {
super.onPause();
finish();
}
}
There are a couple of ways you can stop your thread. If you store your Thread object then you can call interrupt() on it:
progress.interrupt();
This would cause the sleep() to throw an InterruptedException which you should return from, not just print the stack trace. You should also do the loop like:
while(endTime > System.currentTimeMillis()
&& !Thread.currentThread().isInterrupted()) {
You could also set some sort of shutdown flag:
// it must be volatile if used in multiple threads
private volatile boolean shutdown;
// in your thread loop you do:
while (!shutdown && endTime > System.currentTimeMillis()) {
...
}
// when you want the thread to stop:
shutdown = true;
In order to safely quit the thread you must first call thread_instance.interrupt() and then you can check if it is interrupted or not.
Refer this LINK
see this post for kill java thread.The way they recomend is to use a shared variable as a flag which asks the background thread to stop. This variable can then be set by a different object requesting the thread terminate.
I have a basic asynchronous task that performs a web request. The thread is not contained in a loop or anything, it performs the request and returns from run(). When I try to execute another request, using that thread, I get an exception thrown because the thread is already running. I've searched around a lot on this site for answers, but all that seems to come up is stopping threads that are in a loop, basically forcing the thread to return.
Should I just put the request code in the thread into a loop that waits on some kind of flag from the main thread to tell it to go ahead and execute again? like:
public void run()
{
while ( threadIsStillRunning )
{
while ( !threadShouldExecute )
{
//Sleep the thread
}
//Execute the request
}
}
EDIT:
Ok, well here's the thread (this is contained in one of my class objects-WebServiceHelper):
private Thread executeRequest = new Thread()
{
public void run()
{
//Meat of the code
isRunning = false;
}
}
I then have another class method in the same class(WebServiceHelper):
private volatile boolean isRunning = false;
public void Execute(WebServiceHandler handler)
{
while ( isRunning )
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
isRunning = true;
r = handler;
executeRequest.start();
}
where r is just an interface object that I use to perform callbacks to the object performing the request.
Then in my main activity (the one that requested the thread execution i have this:
private Runnable getSiteData = new Runnable(){
public void run(){
mWebServiceHelper.SetMethod("GetSiteData");
mWebServiceHelper.Execute(mySiteHelper);
}
};
public void downloadDidFinish(List<Map<String, String>> data)
{
// TODO Auto-generated method stub
TeamList.StoreTeams(data );
mHandler.post(getSiteData);
}
downloadDidFinish gets called by the thread above upon completion, I then perform another request right after as you can see. The crash is happening when I try to call Execute again on the WebServiceHelper and start the thread again.
Asynctask is very useful to manage your threads.
https://developer.android.com/reference/android/os/AsyncTask.html
https://developer.android.com/resources/articles/painless-threading.html
Here is an example: http://labs.makemachine.net/2010/05/android-asynctask-example/
I have a Service that launches a Thread and a Runnable like so.
t = new Thread(new Runnable() {
public void run() {
doSomething();
}
});
t.start();
The reason for the thread is to perform an Async task doSomething(). For now lets not worry about the other class AsyncTask. I have tried it and it does not work for my case. Edit: I can't use AsyncTask because it is meant for the UI thread only. This piece of code has to operate inside a Service, so nope, no AsyncTask :(
doSomething() contains some external libs so the issue I am having is that it can potentially be hung at one of the commands, without return any value (hence no error checking can even be done)
To work around this, I will want to, at some point of time, destroy the Service.
stopService(new Intent("net.MyService.intent));
This works fine and is easily verified on the phone. However, the Thread which was created above will continue to run even when the Service that spawned it is destroyed.
I am thus looking for the correct commands to insert in the Service's onDestroy() which will clean up the Thread for me.
t.destroy();
t.stop();
are both depreciated and cause application crashes.
I took this code from somewhere
#Override
public void onDestroy() {
Thread th = t;
t = null;
th.interrupt();
super.onDestroy();
}
but it still does not work, the thread continues to run. Any help guys?
The thread destroy and stop methods are inherently deadlock prone and not safe. Their existence also gives the illusion that there might be some way of halting another thread immediately when something else tells it to.
I understand your thinking, from your point of view their is one main thread, and when this thread hasn't received a response from it's worker thread in a while you'd like to kill it and restart it, without caring what it's up to. But the reason those methods are deprecated is you should care what the thread is up to. A lot.
What if the thread has a lock around a variable you need to use later? What if a thread has a file handle open? In all these cases, and many more, simply stopping the thread at it's current operation would leave things in mess -- quite likely your application would just crash further down the line.
So in order for a thread to be interruptible or cancel-able or stoppable, it has to manage this itself. If a thread or operation provides no way for itself to be interrupted, then you cannot interrupt it - it is assumed to do so would be unsafe.
If you runnable is literally
public void run() {
doSomething();
}
then there is no way to interrupt it. One would hope that if doSomething were a long operation that there might be a way to either interact with it incrementally with something like
public void run() {
while (running) {
MyParser.parseNext();
}
}
or to be able to pass in a variable by reference which indicates whether the thread is interrupted or not, and hopefully the method would interrupt itself at suitable location.
Remember a blocking operation is blocking. There is no way to get around that, you cannot cancel it part way through.
Alternative answer
Use the following code:
MyThread thread; // class field
Create and start the thread as you do it right now.
thread = new MyThread();
thread.start();
When the service is destroyed, "signal" the thread to quit
public void onDestroy() {
// Stop the thread
thread.abort = true;
thread.interrupt();
}
Here is thread implementation
//another class or maybe an inner class
class MyThread extends Thread {
syncronized boolean abort = false;
//ugly, I know
public void run() {
try {
if(!abort) doA();
if(!abort) doB();
if(!abort) doC();
if(!abort) doD();
} catch (InterruptedException ex) {
Log.w("tag", "Interrupted!");
}
}
}
You might want to read the following:
How do you kill a thread in Java?
Thread Primitive Deprecation as already pointed by Claszen
http://www.devx.com/tips/Tip/31728 - based my code from here, but there are some issues with the code!
I think that you could rely on catching the exception and not check abort but I decided to keep it that way.
UPDATE
I've seen this sample in codeguru:
public class Worker implements Runnable {
private String result;
public run() {
result = blockingMethodCall();
}
public String getResult() {
return result;
}
}
public class MainProgram {
public void mainMethod() {
...
Worker worker = new Worker();
Thread thread = new Thread(worker);
thread.start();
// Returns when finished executing, or after maximum TIME_OUT time
thread.join(TIME_OUT);
if (thread.isAlive()) {
// If the thread is still alive, it's still blocking on the methodcall, try stopping it
thread.interrupt();
return null;
} else {
// The thread is finished, get the result
return worker.getResult();
}
}
}
Did you check the Java Thread Primitive Deprecation Documentation which is referenced in the Thread API JavaDoc. You will find some hints to handle your problem.
why don't you use an AsyncTask?
A task can be cancelled at any time by
invoking cancel(boolean). Invoking
this method will cause subsequent
calls to isCancelled() to return true.
After invoking this method,
onCancelled(Object), instead of
onPostExecute(Object) will be invoked
after doInBackground(Object[])
returns. To ensure that a task is
cancelled as quickly as possible, you
should always check the return value
of isCancelled() periodically from
doInBackground(Object[]), if possible
(inside a loop for instance.)
I like to take the following approach:
class MyHandler extends Handler {
final Semaphore stopEvent = new Semaphore(0);
#Override
public void handleMessage(Message msg) {
try {
while (!stopEvent.tryAcquire(0, TimeUnit.SECONDS)) {
doSomething();
if (stopEvent.tryAcquire(SLEEP_TIME, TimeUnit.MILLISECONDS)) {
break;
}
}
} catch (InterruptedException ignored) {
}
stopSelf();
}
}
On service onDestroy just release the stopEvent:
#Override
public void onDestroy() {
myHandler.stopEvent.release();
myHandler = null;
super.onDestroy();
}
Better to use global variable stopThread, stop thread once variable changed to true.
btnStop.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0){
stopThread = true;
}
});
public void run() {
while (!stopThread) {
//do something
}
}
I think the best way to create and communicate with another thread is to use an AsyncTask. Heres an example of one:
public class Task extends AsyncTask<Void, Void, Void> {
private static final String TAG = "Task";
private boolean mPaused;
private Runnable mRunnable;
public Task(Runnable runnable) {
mRunnable = runnable;
play();
}
#Override
protected Void doInBackground(Void... params) {
while (!isCancelled()) {
if (!mPaused) {
mRunnable.run();
sleep();
}
}
return null;
}
private void sleep() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Log.w(TAG, e.getMessage());
}
}
public void play() {
mPaused = false;
}
public void pause() {
mPaused = true;
}
public void stop() {
pause();
cancel(true);
}
public boolean isPaused() {
return mPaused;
}
}
You can now easily use this class, and start the thread by writing:
Task task = new Task(myRunnable);
task.execute((Void) null);
Along with this you can easily pause or stop the thread from looping:
Example of pausing and playing the thread:
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (task.isPaused()) {
task.play();
} else {
task.pause();
}
}
});
Example of stopping and starting the thread:
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (task.isCancelled()) {
task = new Task(myRunnable);
task.execute((Void) null);
} else {
task.stop();
}
}
});