Most Android framework components are not thread safe—at least this is the assumption that I usually work with.
However, is it safe to invoke startService() from a background thread?
I came across a post from Dianne Hackborn who says that it is safe to call sendBroadcast() from any thread, so I want to assume that this is also true for startService() (http://groups.google.com/group/android-developers/msg/38a09b52de93f70a).
Can anyone with framework experience comment?
Thanks!
I don't know the theory but I believe the answer is yes, and it is easy to try. Just be sure that as always, if you are going to update anything on the UI, to put a Handler in your main thread - and then in the Service, send that Handler a Message containing the data to be put on the UI.
Related
Hopefully someone can explain this to me or point me to a resource I can read to learn more. I am building an app that uses a ListView and a custom list adapter that I modeled off one of the many tutorials available online such as this one:
http://www.softwarepassion.com/android-series-custom-listview-items-and-adapters/
It worked fine. However, every example of how to do this runs the process of building the list of objects to be displayed and collecting the required data on separate threads.
I want to know why/couldn't you just put everything into onCreate? I can't see a reason why you would need separate threads to make this happen. Is there some general form/standard for when/what must me run on certain threads?
The Android docs on this are very good, as with most things.
The upshot is: the UI should always be responsive. So if you have some operation that will take enough time that the user will notice, you might want to consider not running it in the UI thread. Some common examples are network IO and database accesses. It's something of a case-by-case basis though, so you have to make the call for yourself a bit.
Well, if building the list of objects is not a relatively short process, doing it in onCreate() would be blocking/slowing the main thread. If you use a separate thread, it will allow the android os to load all of the UI elements while you are waiting for the list to be populated. Then when the list of objects is ready, you can instantly populate the already initialized UI, as opposed to waiting to initialize the UI until after the list of objects is built. It ensures that your application will always be responsive for the user.
Because you only have 0.5 sec to execute onCreate — after which the dreaded ADN (application not responding) error message is displayed. So unless your list view is super simple you won't make it it in time. And even if your list view is super simple it is better to learn it the proper way.
BTW: I don't even use threads, I use one or more Services to do all the work. Even more difficult to implement but more robust and responsive as well.
The reason you don't do things in onCreate or on the UI thread is for responsiveness. If your app takes too long to process, the user gets shown an App Not Responding dialog.
my teacher once said: every software can be written in a single (big) for loop.
And if you think: it can be... maybe at NDK level.
Some SDK developers wanted to make the software developers tasks easier and that's, why exists the SDK's and frameworks.
Unless you don't need anything from multitasking you should use single threading.
Sometimes there are time limitations, sometimes UI/background/networking limitations and need to do stuff in diff threads.
If you see source code of Asyntask and Handler, you will see their code purely in Java. (of course, there some exceptions, but that is not an important point).
Why does it mean ? It means no magic in Asyntask or Handler. They just make your job easier as a developer.
For example: If ProgramA calls methodA(), methodA() would run in a different thread with ProgramA.You can easily test by:
Thread t = Thread.currentThread();
int id = t.getId();
And why you should use new thread ? You can google for it. Many many reasons.
So, what is the difference ?
AsyncTask and Handler are written in Java (internally use a Thread), so everything you can do with Handler or AsyncTask, you can achieve using a Thread too.
What Handler and AsyncTask really help you with?
The most obvious reason is communication between caller thread and worker thread. (Caller Thread: A thread which calls the Worker Thread to perform some task.A Caller Thread may not be the UI Thread always). And, of course, you can communicate between two thread by other ways, but there are many disadvantages, for eg: Main thread isn't thread-safe (in most of time), in other words, DANGEROUS.
That is why you should use Handler and AsyncTask. They do most of the work for you, you just need to know what methods to override.
Difference Handler and AsyncTask: Use AsyncTask when Caller thread is a UI Thread. This is what android document says:
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
I want to emphasize on two points:
1) Easy use of the UI thread (so, use when caller thread is UI Thread).
2) No need to manipulate handlers. (means: You can use Handler instead of AsyncTask, but AsyncTask is an easier option).
There are many things in this post I haven't said yet, for example: what is UI Thread, of why it easier. You must know some method behind each kind and use it, you will completely understand why..
#: when you read Android document, you will see:
Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue
They may seem strange at first.Just understand that, each thread has each message queue. (like a To do List), and thread will take each message and do it until message queue emty. (Ah, maybe like you finish your work and go to bed). So, when Handler communicates, it just gives a message to caller thread and it will wait to process. (sophiscate ? but you just know that, Handler can communicate with caller thread in safe-way)
I am aware this is most likely a very stupid question, but I just cannot completely understand the point of Handlers. I know the idea is that Handlers execute on the main thread, and they seem to be most commonly used along with worker threads, but why cannot the worker thread just invoke methods on the calling Activity instead of said Activity creating the thread along with a Handler to receive messages?
Again, I apologise for the ignorance of my question, but all I've found online is tutorials on how to use Handlers and my Pro Android 3 book does not clear up my question (or I'm too stupid to understand it properly!)
Or, for that matter, why use them over AsyncTasks, which can modify the UI without problem?
Thank you.
When using handler (or message) each task becomes "serialized".
This has the advantage that there is NO concurrency and therefore no need to lock.
It is much easier to make a message driven system stable than an multi-threaded one.
By the way AsyncTask uses Handlers, too
Using handlers directly give you more flexibility.
For example you could schedule a message to be send in the future.
Or you could abort an scheduled message.
Handlers are a very powerful tool.
I would like to know, once for all. I've read in many places. When I want do some 'long time operations' I should use a Handler.
But I don't get why? All my 'long-time-operations' I surround with a regular threads, and it works fine.
Why would I use Handler for this?
The only time I had to use Handler was, when I had to schedule some task(postDelayed)
Is there any main idea I miss about handlers(When I should really use it)? Or maybe there isn't really difference?
A Handler lets you communicate back with the UI thread from your background thread. This is because UI operations are forbidden from within background threads. Note that starting at version 1.5, the AsyncTask class makes it much easier to do so.
It can't just be about getting you back to the UI thread since runOnUiThread(Runnable) does that very nicely. I suspect this is more about making it easier for Android to manage threads and other resources that shouldn't live outside of an Activity's context, and that the "Activity has leaked..." exceptions tell you when that's happened.
I am writing a home screen widget following Jeff Shakey's tutorial, http://android-developers.blogspot.com/2009/04/introducing-home-screen-widgets-and.html.
This tutorial uses service to avoid any ANR timeouts. I just wonder, can I use Thread instead of service to do the work of getting data and updating RemoteViews? I don't want to create a service, because Thread is easier to handle and pass data into Thread.
Thanks.
You should not rely on thread. It is not guaranteed to work. From experiences in a similar situation the thread approach worked on the emulator and the samsung galaxy but not reliable on the g1. So you should really attempt to use a service. It is quite easy: define in your manifest and startService. It is a little more cumbersome to pass data via an intent but it is manageable and the whole approach is definitely more robust.
I read an article saying that, to avoid ANR, service is sometimes not enough. Thread is needed.
See: http://blog.elsdoerfer.name/2009/06/03/writing-an-android-widget-what-the-docs-dont-tell-you/
"you are encouraged to use a service to perform your widget updates if you are doing anything that might take a little longer, in order to avoid Application Not Responding (ANR) timeouts. However, this will usually not be enough. ......
The solution is to have your service start a separate thread. For an example, see Jeffrey Sharkey's android-sky Widget."
Any thoughts?
Here's scenario:
Client makes remote call to the service (returns void) and provides
a callback object
Service executes some long running logic on the background thread
and then uses callback object to trigger ether success or failure
which (since these manipulate visual elements) execute in
Activity#runOnUiThread block
The scenario runs fine. The question is - can I use AsyncTask to make
code less verbose (how?) and would be there any advantages in doing it
that way?
Or should I just get away from client callbacks alltogether and
execute remote service calls retrofitted to return some value within
AsyncTask#doInBackground?
It is difficult to say whether AsyncTask will make things less verbose, since we don't know the verbosity of your current implementation.
For me, AsyncTask means I don't have to worry about cleaning up threads myself (e.g., post some sort of kill job to a LinkedBlockingQueue my background thread is waiting on). It also eliminates the custom Job classes I used to create for using with LinkedBlockingQueues. And, it simplifies a bit doing final work back on the UI thread.
In your case, with a remote service, the UI thread issue is less critical, since the activity needs to handle that itself.
I don't see what the difference is between your #2 and your last paragraph. In both cases, your service will call the callback object, which will use something like runOnUiThread() to arrange for the work to be done on the UI thread.
AFAIK, the only two ways to have a service doing any sort of asynchronous work let the client know that work is done is by a broadcast Intent or a callback object. Broadcast Intents are convenient but public (i.e., other code can watch for them).
I suspect I probably have not helped much here, but I just don't know enough of your scenario to provide greater detail.
I'm having quite the same question : i'm developping a map activity, with a 'lazy-loading' functionnality (xml from Network, parsing it, then updating my map with the 'items' created from that parsing...)
i wondered what would be 'the best' way to implement it...
async service launched from a thread, an update notification via Intent?
just a thread (no service, since i don't need to expose it to other applications) w/ callback
asyncTask with callback
i'm comparingthese in terms of speed, using the Android SDK performance analysis Tool traceview
I guess a more precise answer might be found from Android contributors on the Android-developper-group...