Sorry but, I'm quite a bit confused after reading this.
If let say, I have a single Activity and inside it,
I tried to make an inner Class implementing Thread that has looper and handler.
My question is;
If I finish() my activity. Is that close any Looper / Handler i just created last time?
I'm afraid the Thread is still running background altough the Activity is already closed -> ended.
After finish, you don't have to care about Handlers attached to the Main Thread, because it's Looper (and the Thread itself) is managed by the system, and it will quit when it is necessary.
However if the Handler is attached to a separate Looper that is not managed by the system (for example a Thread with a Looper started by you), it will be there in case you have not stopped the relevant Thread (that has the Looper). This true in general for all Threads, the fact that the Thread has a Looper does not change the situation.
So the important think here is to stop every Thread that you started manually.
As an addition:
You can always check your running Threads in Eclipse. Just attach the
debugger and go to the Debug view. All Threads will be listed there.
Take a look at HandlerThread.
Related
This question already has answers here:
Android - What happens to Threads when a Activity finishes?
(2 answers)
Closed 6 years ago.
If we start a handler thread / thread in an activity and then the activity is destroyed when we press back button, What happens to the handler thread?
Is it still in running state?
If Yes When the thread execution will stop?
Simply , your Thread is in running state.
It is actually bad practice to keep a thread running after onPause. The reason is that after onPause your application may drop out of memory at any time without your being able to know, therefore you will not be able to clean up after yourself.
The proper way to do it is stopping the thread onPause and recreating it onResume. If you need state you can use Android's built in saveState methods or settings or whichever to keep that.
Your related thread is here and here
The thread won't be destroyed until its job is finished. So make sure all its job is finished before closing an activity. Because the thread may contain any reference of views and it may try to access it after the job is done. HandlerThread can be stopped by calling
thread.quitSafely();
this ensures that all pending messages are processed before the thread stops.
I am using the thread for login on Server and I want to stop the Thread as the user press back button, I am using stop() and destroy() method and these methods crashing my application, I think these Methods are depreciated that why I am facing this problem. Please Give me the way to stop thread without using stop() and destroy().
Thread.stop() is deprecated since java 1.1 (~17 years ago...). Java of this method explains the reasons in details. This means that you should never call this method. It is still there for backwards compatibility with code written when I was young.
But what to do if you want to "cancel" the operation done in thread? The answer is that you (developer) should care about this yourself. How? It depends on your application. If for example your thread opens i/o stream you can close the stream. If your thread performs series of operations in loop you should check special flag that indicates that thread should exit and update this flag according to needs of your application (in your case when user presses "back" button.
If you still have problem please try to give more details what does your thread do and you will probably get concrete recommendations how to stop it.
For background thread in android try to use service.
I mean you start a service and put a thread in that service.
If you want to stop that service then pressed back button try "Bound" Service. You will get basic idea here.
http://developer.android.com/guide/components/services.html
Only use a thread if you want to do work repeatedly for a long time. I have never needed to start a thread.
You should look at using an AsyncTask.
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
It works by using a Thread from the ThreadPool. AsyncTask's are easy to stop, have a method to override for background tasks and one to override for post task work which is suitable for updating the UI (as long as the task was started by the UI thread).
I wrote an app on android in which a thread is created through the main activity(UI thread), the new thread saves the activity instance and then calls a method in it while running.
I got an error "Can't create handler inside thread that has not called Looper.prepare()" and found out in this post:
Can't create handler inside thread that has not called Looper.prepare()
and in many more questions that i can't call a method of another thread directly, i should use runOnUIThread or doInBackGround and so on...
my question is WHY?
what's wrong with that design?
thanks in advance :)
You seem a bit confused - the question does not make much sense, so it's quite hard to answer.
Bits and pieces:
creating a thread in UI thread that "saves the activity instance" is wrong in itself: lifecycle of activity is complicated and you should not refer to it by instance.
you cannot "call a method of another thread" (unless you mean the java.lang.Thread object itself, and from the context it seems that you don't), because objects do not belong to any thread. All objects in Java live on heap and can be accessed by any thread.
BUT since each thread is an object, you can have a Map that holds objects indexed by thread instances. This is basically what ThreadLocal is.
Android introduces concept of "Loopers" - you can build one in any thread and call it; if you do, you can say that the thread "has a looper". A thread that has a looper is stuck in a loop, doing any work that handlers pass to it, and - after finishing each task - waiting for another to come by. This is what the main thread does all the time. If you build a handler instance, the handler can be called from any thread, but is connected to the looper of the thread that called the constructor.
Since handlers work by passing work to loopers, they can only be built in threads that have loopers.
I am not sure what you want to achieve, but the bottom line is:
your idea of holding a reference to Activity is wrong - just let it go (and use Loader API or a Service)
you try to build a Handler instance on some custom thread that has no Lopper (probably adding the looper is NOT what you want, instead you want to build the Handler in your main thread)
you imagine objects as being owned by threads - try to get rid of this idea, it skews your way of thinking.
I am currently developing Android app, it needs download content from internet. I use thread to do that and then call runOnUiThread method to update GUI.
I placed a refresh menu on it, if user tried to refresh the content, the download thread will be created and started. The problem is that how can I control the thread order, I need to accept the latest request's response and abandon previous thread requests if there were some other requests still running because the request parameters may have been changed by user. Currently I was using a threadId to do this thing, when a thread finished, it will check its threadId, if it was the latest recored one, it then takes control and render the response. My question is that is there any other proper better solution for this?
Do I need to stop threads when user exit the app? I remember that some book said that do not try stop thread manually and wait itself finish is a good practice, is that true? Should I stop them by calling "stop" or "interrupt" method?
I read some documents around threading in Android and found the class HandlerThread, what is it? In what kind of situation I need to use it?
Rather than starting a new thread for every refresh action I would create a single thread for all the background download work that loops and downloads content as lined up in a queue. That ensures that you don't download content concurrently and also saves resources.
In the GUI you simply queue a refresh request whenever the user prompts you to and can abort a running download by calling HttpRequestBase.abort on the http method instance. The background thread should receive and catch a SocketException and move on to the next queued request.
To end the background thread you just have to end its loop. You can use the Looper and Handler classes to help you with all of the above, the HandlerThread class you mentioned is simply a handy class to create a thread that has a Looper.
The problem with interrupting a thread is that it won't break you out of a blocking I/O request and handling an InterruptException correctly can be complicated. So depending on the situation I would say yes, it is better practice to end the thread by returning from its run method.
i discover this week AsyncTask, and i replace Thread by AsyncTask in some place in my program,
You have doc & sample here, really easy to use :
http://developer.android.com/reference/android/os/AsyncTask.html
when i was using thread GUI was lock, and now it's not locked.
And it's possible to cancel a AsyncTask (but i never try)
You can use an IntentService to start your background operations, the service will operate as "work queue processor" and will execute your calls in order.
I know that this problem is caused by the sleep or wait calling on the main thread and that the answer on how to solve this will be to put the method into a seperate thread and then make that thread sleep. But the code is a mess and don't really have the time to sort it out and split it up into separate threads and was wondering if there is any other way of doing this? Even if it is not the cleanest or most common practice for working with GUIs. I only need about a seconds pause from the method.
You can't do it without creating a separate thread. Creating a thread in Java is easy. The only thing to pay attention to is that you can only touch the UI through the main thread. For this reason you need to use something like SwingUtilities.invokeLater().
It is not possible to sleep on an event thread and not cause a GUI freeze. However in Swing, the event thread is created and managed behind the scenes - you main thread (the one originating from main() method) is not the event thread.
So, you can safely sleep on your main thread.
Using a separate thread for the code is your only solution. Every action started by the Swing thread must be delegated to a separate thread if it would otherwise block the GUI.
I wrote a super simple delay function for java that doesn't let your GUI freeze . It has worked everytime i have used it and i guess it will work for you too.
void Delay(Long ms){
Long dietime = System.currentTimeMillis()+ms;
while(System.currentTimeMillis()<dietime){
//do nothing
}
}
For eg : To delay a thread by 5 millisecods use Delay(5L)
And where would one declare this thread. Please bear in mind any, any reference to a function that contains thread sleep will cause the main thread to pause. Because the main thread will have to wait the the sub thread to pause.
The reality is that threads don't realy work as seperate independant thread because a thread must be started from another thread. In other words if you are creating desktop application, and even if you don't work with other threads, your application is a one threaded application. Now if you start working with threads & putting them to sleep, you will soon find out that that you won't be able to do anything else in the application. No & no the other threads won't even run because they are waiting the first thread to finish sleeping. Why is this? Cause the thread are sub threads of the main thread and it is the main thread that is waiting for that sleep sub thread to wake up. You can't design a threadless application either as java is single main threaded application. Any, yes any, thread further defined in your application always runs inside in the main thread.
Unless somebody can prove me wrong, you obviously whould never pause your main thread as this would lock up your app. However as soon you define another thread and suspend it with sleep() this also locks up your app as the thread was defined in subclass of the main application and therefore the main thread.
So to put a very very long story to bed, pausing a user defined thread, is almost exactly the same as if your called the Thread.sleep() for anywhere in your app, it
pauses the entire application.