I'm new to Android and Java. I need some clarification about threads and their relationship with activities. I'm thinking for this case: A code running in background that can be visible for two activities. I don't know if this can be achieved using threads. From what I've read, there would be no problem using a service, but I'm not sure in the case of threads, so here my questions: If a thread is running in background, can it be "visible" for two or more activities? For example, the most basic sample about thread changes the text in some activity or update the value for a progress bar but, can this same thread be used to do the same in a second activity? Or I need to create a new thread for the second activity that do the same? Is a Service better approach for this case?
Thank you.
If a thread is running in background, can it be "visible" for two or
more activities?
If I understand "visible" as it can access these Activity instances then yes, why not? It's just another object.
For example, the most basic sample about thread changes the text in
some activity or update the value for a progress bar but, can this
same thread be used to do the same in second activity?
Of course. Just keep in mind that the only thread that can draw UI is the UI thread (also called main or system thread). To do any UI update from any other thread you created, you need to call runOnUiThread().
Is a Service better approach for this case?
If this thread is only for updating your app UI, then a background thread is the best solution. A Service will keep running after your app has closed and also you would need to do IPC to communicate app and service, which is slower and requires more code.
You also might consider using AsyncTask instead, it is more suitable for your case because some of its methods run directly on the UI thread (so you don't need runOnUiThread)
Related
Until today, I used services by starting them, using startService(), because I needed to do work also when all the activities was destroyed.
Now, I have a task that needs to be done in the background as long as my activity is alive.
Is there a reason for me to bind the activity to a service instead of doing the work in a separate thread?
It leads me to the question in the title:
Why would anyone want to bind service (without creating it before), instead of using a Thread?
Services and Thread have two different goals. As you mentioned, Service can live longer after the activity was destroyed. Depending on the Service you subclassed it runs or not on the UI Thread. They have their own life cycle and are a construct of the Android SDK. Threads are unit of executions whose flow is parallel to the ui thread. It allows you to execute long term tasks leaving the ui responsive. The Thread lives as long as its run's method. You should make sure that its execution is completed before your Activity or Fragment calls its onDestroy method.
Why would anyone want to bind service instead of using a Thread?
The answer is it depends. If you need to run your task also when you Activity is destroyed, then a Service is the natural choice. Otherwise you can use a simple thread. Think, for instance, about downloading a huge file from the net. You want to run this task also when the activity is not at screen but, at the same time, you want to show to the user the current progress (in percentage maybe) of the download. If you are using a Service to run this task, this one holds also those information. To update your UI, which is part of the Activity, you could either Broadcast those information, or retrive the Service object, the one you get when your service is bound, to retrieve this information (providing a delegate). Since you get an instance of your service, you can use it to send different kind of commands (e.g. stop the download).
Is there a reason for me to bind the activity to a service
instead of doing the work in a separate thread?
If your thread lives in a non static member variable of the activity and the activity is recreated after screen rotation your thread is lost or has to be recreated.
With a service you can reconnect to the service after rotation.
Instead of using a naked thread or a service i prefer to use a LoaderManager with an AsyncTask to do the background task while the activity is visible. The LoaderManager is also capable of reconnecting to the running AsyncTask
I avoid using static member variable for thread/AsyncTask because of memory leaking issues.
I have a application in which I have a UART (Serial Comms) to service and several other "tasks" that require separate worker threads to keep the UI responsive. My problem is in understanding when/where I should create these threads and when they get terminated. Currently, I am creating them in the OnCreate() of the main UI Activity. But, this is causing havok, as I recently needed to "jump" from one Activity back to the Main activity. The recommendation was to use an Intent and StartActivity() with the appropriate flags to "clear to top". But, this of course causes a whole new set of instances for my threads, and everything unravels. Should I be using a Service, tied to my UI somehow? I have subclassed my Main Application, so I have the OnCreate() of my Application. I'm leaning towards that, but can't seem to grasp the life cycle of the Application versus the Activities.
Use a service. You have an ongoing task that isn't inherently attached to one particular activity.
You can start a long running task with startService and the service will not be killed until it's finished. Meanwhile, Context#bindService will keep the service alive as long as anything is bound to it.
General rule of android concurrent programming
If you need to do something off the UI thread and return a result, use an AsyncTask created when you want to use it
If you have a 1 off requirement to do some work (say post a webservice request), use an AsyncTask
If you repeatedly want to do something inside a single activity but you don't need to run after the activity is destroyed or send data to another service, use a thread
If you need to talk to multiple activities, use a service.
If you need to run before/after your launching activity ends, use a service
I just read Android Architecture Tutorial: Developing an App with a Background Service (using IPC). It is basically
Have a service run in separate process.
A repeated timer event will occur in the service.
Within the timer event handler, it will perform networking to retrieve tweet, and inform all the listener attached to it. Listeners are attached to it through IPC.
I can see there are 2 major characteristics with this approach.
Tweet retrieving action run within separate process.
It always run, even the main activity has quit.
However, if "It always run" is not my requirement. I want everything to stop when I quit my main Activity.
Will it be better, if I use AsyncTask (Or Timer) within my main Activity, to perform tweet retrieving action? Everything will be run within single process. No more using Service.
Using AsyncTask (Or Timer), seems simpler. We no longer need to deal with IPC.
Or, using Service approach might be better? Am I missing some goodies provided by Service?
Using service is a better approach as it will allow you to perform the polling independent from the application flow.
As it is a task where no user interaction is required and it has to be done in the background without disturbing the main UI of application and whatever the user is doing, a service is an ideal candidate for its implementation.
It is possible to bind the service with the application in such a way that when the main application terminates, it will also turn off the service.
I would take the view that a TimerTask can be set to execute and repeat at a given interval, Timers run on a separate thread so all this work would occur in the background without disturbing the UI. It would be easy for you to trigger an update within your app when the TimerTask completes and update the UI when you want.
When you exit the app it's a simple case of calling cancel() on your Timer and the purging all the tasks with purge().
Nice and easy and you don't need to implement IPC, which can be very fiddly to get right.
EDIT
Using AsyncTask you can do pretty much exactly the same thing but you'll have to manually schedule the next run. I have used both solutions in the past and found them to work equally well so it's all down to your preference.
At first you have to know, that a service isn't a Thread. If a activity binds a Service and runs as a Deamon, but a ASynchTask is another thread.
ASynchTask's are designed for doing some work which should not running on UI-Thread (for example processing some larger calculations)
Services are designed to run permanantly on Background.
If you want to permanantly check for new tweets, even if your activity is stopped or paused, you should use a Service, which checks into an own thread for new data.
TimerTask are good old java style implementations which run on their own thread.
You can used them for processing some data, but you'll have some problems to manipulation UI. If you want to be it on propper "AndroidWay", use a Handler instead of TimerTask.
First of all, I know the tutorial you are following...I've followed that tutorial myself while trying to learn IPC. One thing you need to know is, The Android docs explicitly say,
Note: Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service.
If at all possible, you should just bind to the service.
Also, you must consider, do you really need a service? Consider that the Android Twitter app doesn't even refresh tweets for you, its on an as needed basis. Polling can be battery intensive, so you must consider if this is really necessary.
Also, will you be using these tweets from multiple activities? If so it would be nice to not duplicate the code in multiple places. So maybe you do want a service in this case.
Other than that, I would recommend that you start simple (Async task with a timer to update it), and move to a service if you think you need it.
Is there any difference in running background threads from an Activity and from a Service that is started by the Activity? Added: The background threads do not interact with the UI.
I currently have some background threads that are launched from the Activity. Most are via AsyncTask and one is through my own ExecutorService. I would like to know if there is a significant benefit to refactoring the code to move these to a Service or IntentService.
You seem to be confused about the definition of Activities and Services. To make it clear:
Activities are things that run according to the Activity lifecycle state machine. The code in the respective handlers interacts with an event loop attached to a UI.
Services are things that run according to the Service lifecycle state machine. The code in the respective lifecycle handlers performs operations to handle things like Intents, etc..., but does not interact with the user via a UI.
Both of these, however, run on the "main thread" of the application. By itself, an Activity or a Service (or Broadcast Receiver, Content provider, etc...) is not a thread. Look at the documentation, and you will see that the Activity and Service classes do not, in fact, form a thread. Instead, they are hooks that will run inside the Android framework, and the framework will at the appropriate time call them on the "main" thread of the app.
You can create separate threads for the app, or use an AsyncTask to do work and publish it to the UI thread easily (something not so easily achieved with a Service).
Threads that are bound to Activities have the same lifecycle. So if you restart/kill the Activity, the thread will also be restarted/killed. This is a problem if you don't manage the lifecycle of an Activity. A service is good in this case. You can have the activity destroyed and still a worker thread running in the background (in the service). But be advised that, if the Android system need resources (memory for example) it will kill the services first (and then restart them according to their Sticky flag). In my opinion, there are no actual benefit in changing threads from the Activity to a Service, since you control the workflow of your activity. If the threads are heavy (and brake the UI for moments) consider putting them in a service on a separate process (in AndroidManifest put the process name of the service).
In Android documentation:
Caution: Another problem you might encounter when using a worker
thread is unexpected restarts in your activity due to a runtime
configuration change (such as when the user changes the screen
orientation), which may destroy your worker thread. To see how you can
persist your task during one of these restarts and how to properly
cancel the task when the activity is destroyed, see the source code
for the Shelves sample application.
What is the difference between Service, Async Task & Thread. If i am not wrong all of them are used to do some stuff in background. So, how to decide which to use and when?
Probably you already read the documentation description about them, I won't repeat them, instead I will try to give answer with my own words, hope they will help you.
Service is like an Activity but has no user interface. Probably if you want to fetch the weather for example you won't create a blank activity for it, for this you will use a Service.
A Thread is a Thread, probably you already know it from other part. You need to know that you cannot update UI from a Thread. You need to use a Handler for this, but read further.
An AsyncTask is an intelligent Thread that is advised to be used. Intelligent as it can help with it's methods, and there are three methods that run on UI thread, which is good to update UI components.
I am using Services, AsyncTasks frequently. Thread less, or not at all, as I can do almost everything with AsyncTask.
This is the easiest answer for your question
Thread
is an unit of execution who run "parallel" to the Main Thread is an important point, you can't update a UI component from the any thread here except main thread.
AsyncTask
is a special thread, which gives you helper methods to update UI so basically you can update the UI even AsyncTask will run on a background thread. Interprocess communication handling is not required to be done explicitly.
Service
solve the above problem because it live separate from the activity that invoke it so it can continue running even when the activity is destroyed, it run in the Main Thread(beware of ANR) use a background service (extend IntentService it create the worker thread automatically for you). Service is like an activity without UI,
is good for long task
Few more information I wish someone had told me a few days ago:
You can share global variables - such as threads - between Activities and Services.
Your application together with all its global variables will not be wiped out as long as there is an Activity or a Service still present.
If you have an instance of a Service in your app and the OS needs resources, it first kills your Activities, but as long as there is the Service, the OS won't wipe out your application together with its global variables.
My use case is like this: I have one thread in global space that is connected to a server and an Activity that shows the results. When user presses the home button, the Activity goes to background and a new Service is started. This service then reads results from the thread and displays information in the notification area when needed. I don't worry about the OS destroying my Activity because I know that as long as the Service is running it won'd destroy the thread.
In short, Service for time consuming tasks, AsyncTask for short-lived tasks, Thread is a standard java construction for threads.
From developer's perspective:
Thread: Used to execute the set to codes parallely to the main thread. But you cannot handle the UI inside the thread. For that you need to use Handler. Hadler binds thread Runnable with Looper that makes it a UI thread.
ASyncTask: Used for handling those tasks that you cannot make to work on the main thread. For example, an HTTP request is a very heavy work that cannot be handled on the main thread, so you handle the HTTP request in the ASyncTask It works parallelly with your main thread Asynchronously in the background. It has a few callback methods that are invoked on their corresponding events.
Service: Works in the background under the same Application process. It is implemented when you have to do some processing that doesn't have any UI associated with it.
service is like activity long time consuming task but Async task allows us to perform long/background operations and show its result on the UI thread without having to manipulate threads.