i am using threads to do few tasks. and after that i want to access the main thread via runOnUiThread(). but how to determine whether that ui thread still running or not?
Two options are there one use a static boolean variable and see whether the activity is running or not, or you can check all the running tasks and determine whether your activity is running or not.
The only instance when your UI thread is not running is when your main thread has spawned a thread which needs to communicate with the UI thread and the non-UI thread has not been killed when the life of the context ends.
You must avoid a situation like this by interrupt()ing your threads in onStop() or onDestory() (whatever is appropriate).
After you've taken care of this, you can always safely assume that a runOnUiThread() call is appropriate.
Related
I am trying to figure out which threads should do what in Android.
The only thing I have found stated in the official documentation is that camera.open() should be put into its own thread.
What about:
camera.startPreview()
camera.stopPreview()
camera.release()
It doesn't state which thread they need. Must they be run on the main thread (ui thread)? Or am I free to choose?
Why am I trying to figure this out? camera.startPreview() when run on the main thread is causing my app to jitter/lag for a short period of time, this heavily affects my application as it is put inside a viewPager and I do not wish to have the camera to always preview (which would cause no lag, but takes up system resources).
Any ideas?
The documentation for Camera states that the class is not thread safe and should not be called from multiple threads at once (I suppose, unless you are performing your own synchronization).
It says that the callbacks will be delivered to the thread that makes the call to open
From the reference (emphasis mine):
This class is not thread-safe, and is meant for use from one event thread. Most long-running operations (preview, focus, photo capture, etc) happen asynchronously and invoke callbacks as necessary. Callbacks will be invoked on the event thread open(int) was called from. This class's methods must never be called from multiple threads at once.
From the open(int) method reference:
Callbacks from other methods are delivered to the event loop of the thread which called open(). If this thread has no event loop, then callbacks are delivered to the main application event loop. If there is no main application event loop, callbacks are not delivered.
Caution: On some devices, this method may take a long time to complete. It is best to call this method from a worker thread (possibly using AsyncTask) to avoid blocking the main application UI thread.
The thread it needs is the one you use to call open(int).
So to answer your question, yes you are relatively free to choose, but you must remain consistent.
My android app has a long running background service, which I also understand runs in the application's main thread and for that reason, any time consuming or blocking task should be moved to a separate thread.
Now, here is the situation, I don't understand/confused about:
When I bind to the service from an activity, i receive an reference to the service which allows me to invoke service methods from my activity. One of the methods allows me to pass a String object from the activity to the service, which is then added to a BlockingQueue. A separate worker thread which is started in the Service's onCreate method, checks the queue for available data and then performs the required task.
What I want to understand is, if at some point, the queue becomes full and an attempt to the queue blocks, will it affect the main thread the service is running on?
Yes. In this situation, if the queue becomes full, the calling thread will block (in your situation, the main thread). So this is a bad design.
The produced data coming from a field of an Activity doesn't force you to use it on the main thread. I suggest you use some Handler for your producer running on its own thread which will allow you to make the processing (and eventually waiting on the queue) outside of the main thread.
This is also good for communicating with your Service since you can use Handlers to communicate with a Service (see Android Services' guide).
Finally, if applying the produced data can be passed directly to an Handler using either
Handler.post(Runnable) or Handler.send(Message)
I am little bit confused with multithreading in Android. I am aware we can achieve using AsyncTask and Handler. Generally when should we implement by extending Thread Class in Android? Can anyone give an example that we need to do it only by extending thread class but not with AsyncTask or Handler.
Consider a example app, we have a bouncing ball in an activity(forget the animation part), I need to change the color of the ball every 20 minutes, and I need to get the color code from the server and update the ball UI. Now how can I achieve this ? Can someone explain using AsyncTask or Handler and also only using Thread Class(without Asynctask or Handler)?
How should I handle downloading large payloads from server using services.
Thread
Long task in general
Invoke by thread.start() method
Triggered from any thread
Runs on its own thread
Manual thread management/code may become difficult to read
AsyncTask
Small task having to communicate with main thread
Invoke by execute() method
Triggered from main thread
Runs on worker thread
Must be executed and created from the main Thread
Service
Task with no UI,but should not use for long Task. Use Thread within service for long Task
Invoke by onStartService()
Triggered from any Thread
Runs On Main Thread
May block main(UI) thread
IntentService
Long task usually no communication with main thread if communication is needed then it is done by Handler or broadcast
Invoke via Intent
Triggered from Main Thread (Intent is received on main Thread and worker thread is spawned)
Runs on separate thread
Can't run task in parallel and multiple intents are Queued on the same worker thread.
Thread: Use it to separate long running computation from Main Thread ( UI Thread). If you don't need to update UI or send messages back to UI Thread, use it for long running tasks. But you don't really need to extend Thread and write your logic by overriding Thread methods. But still HandlerThread is effective compared to java Thread.
AsyncTask : it is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few milli seconds at the most). Recommended for 5 milli seconds task execution.
Service: Use it to handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.
HandlerThread/Handler: A HandlerThread is effectively a long-running thread that grabs work from a queue, and operates on it. You can use it even to send results back to UI Thread via Handler of UI Thread.
Have a look at below posts for more details:
Asynctask vs Thread vs Services vs Loader
Handler vs AsyncTask vs Thread
Creating Background Service in Android
Android: Toast in a thread
An AsyncTask is basically a thread. It has 3 callBack methods(main) and the are executed in this order top to bottom:
1. onPreExecute()
2. doInBackground()
3. onPostExecute()
4. onProgressUpdate()
The onPreExecute() and onPostExecute() are running on the UI thread and doInBackground() is a separate thread as such. If you spawn a thread(not a AsyncTask), and try to set a property of a UI element from it, this will raise an exception saying: the original thread(the UI thread) which created the view can only modify it. So only the UI thread has these two properties:
Only it can add/modify the UI of the App
It cannot be blocked for more than 5 secs(ANR exception)
So to over come both these limitations in one go, we have AsyncTask, it can run resource consuming operations(network access, implementing gaming logic etc) in doInBackground(), and still provide ability to alter the UI from onPreExecute() and onPreExecute().
I think title itself says what the my question is...
AFAIK, in Java, when work of a Thread is completed i.e. run() method has completed executing, Thread itself will finish and dies.
So, When my Activity(I mean UI) is idle for a long time, what the UI thread will do? does it sleeps? or does it do any other work?
Thanks to all...
I believe the question is not really about Java threads in general, but about the Android "main thread" (also called the "UI thread").
To quote from the JavaDoc for the Android Handler:
When a process is created for your application, its main thread is
dedicated to running a message queue that takes care of managing the
top-level application objects (activities, broadcast receivers, etc)
and any windows they create. You can create your own threads, and
communicate back with the main application thread through a Handler.
This is done by calling the same post or sendMessage methods as
before, but from your new thread. The given Runnable or Message will
then be scheduled in the Handler's message queue and processed when
appropriate.
In other words: The main thread is responsible for dequeuing messages/runnables from a queue and processing them. That main thread is blocked while the queue is empty (since there is nothing for it to do). If you use a Handler that was created in the main thread, that Handler's messages and runnables will actually be added to the same queue used by the main thread. Normally, the main thread will run as long as the process does.
Note: An Android app can actually have multiple processes, and each one will have its own main thread. However, most Android apps will only have one process (and therefore one main thread).
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.