What is the cons of using Thread instead of using Android Service in an App for long running task. What will happen if I don't use Android Service for long running task?
Service:
A service is a component which runs in the background, without direct interaction with the user. As the service has no user interface it is not bound to the lifecycle of an activity.
Services are used for repetitive and potential long running operations, like Internet downloads, checking for new data, data processing, updating content providers and the like.
It is possible to assign services the same priority as foreground activities. In this case it is required to have a visible notification active for the related service. It is frequently used for services which play videos or music.
Threads:
They are simple runnable threads. You can execute non UI stuff with these threads but you can't perform UI tasks in them (as UI is not thread safe). For dealing with UI in these threads, you will have to use Handlers, which is quite cumbersome for beginners to get a grip and understanding of them.
So depending on your needs and app you can choose the one best suits you.
A Service is an application component that can perform
long-running operations in the background and does not provide a user
interface. Another application component can start a service and it
will continue to run in the background even if the user switches to
another application. Additionally, a component can bind to a service
to interact with it and even perform interprocess communication
(IPC). For example, a service might handle network transactions, play
music, perform file I/O, or interact with a content provider, all
from the background.
On other hand, Threads are the cornerstone of any multitasking
operating system and can be thought of as mini-processes running
within a main process, the purpose of which is to enable at least the
appearance of parallel execution paths within applications.
They are to be used as per requirement and we cannot actually point out pros and cons of either of them as both of them are essential in different situations.
What will happen if I don't use Android Service for long running task?
You might get lucky and your code finishes. Then again, you might not get lucky, and your code gets killed at a random point in time.
Aside from the textbook descriptions of what an Android Service is and what a Thread is, the main difference between the two which is directly relevant to your question is how the OS threats them.
A thread is a way to execute code in the background, while a service is a way to make Android aware you are executing code in the background.
As far as the underlying Linux kernel is concerned, it knows only about threads, and cares about them only with regards to thread switching and prioritization. Whether there is a service has no impact on this.
However, as far as the Android device memory management and task prioritization goes, Android does not know or care about threads in your process. It only knows about services, and interacts with them on the main app process thread only.
Thus, for as long as you have a thread alive, the kernel will happily try to keep the process alive and allocate CPU time for that thread execution.
However, unless you have an activity, service, content provider, or a broadcast receiver alive, the Android memory manager might decide to kill your process to reclaim its resources for another higher priority process, no matter what threads might be working at this point.
Therefore, while you could go away with running stuff on a separate thread if the user is interacting with your activity, if you want to make sure the background task finishes successfully and is not interrupted at a random point, you need to wrap it in a service (preferably one that is bound by an activity, or is elevated to UI priority by showing a notification).
Note that having a service does not guarantee you that its code will be running in the background. Android will call the lifecycle methods (onStartCommand/onBind/onCreate/OnDestroy) on the main thread of the application process. Your code will have to start a thread to ensure true background execution.
Services are highly recommended and used in Android to do both foreground and background tasks. Instead of going into the definitions I would highly recommend you to look into IntentService class specifically in Android. Available from API Level 3 this class does most of the worker thread heavy lifting for your background task. This class handles asynchronous requests expressed as Intents. Clients send request using startService(Intent) calls. The service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work. Coolest thing you can use this along with an AlarmManager implementation to do say what you want to do every 10-15 mins and still not worry about threads and handler explicit implementation as you would have to if you use Service class.
Here is a short bit of code on how to implement it.
public class UpdateService extends IntentService {
public UpdateService() {
//constructor
}
#Override
public void onCreate() {
super.onCreate();
//Called by the system when the service is first created.
}
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStart(intent, startId);
return(START_REDELIVER_INTENT); //Intent Relidelivery
//You should not override this method for your
IntentService and remember onStart() for IntentService is
deprecated.
}
#Override
protected void onHandleIntent(Intent intent) {
//do your main background tasks here forget about threading doing anything
in here Android will do the heavylifting as required
}
#Override
public void onDestroy() {
super.onDestroy();
//finalize your objects GC etc here
//Called by the system to notify a Service that it is no longer
used and is being removed.
}
}
Services are best implementations for long running tasks that you don't need user input or ui updates right away. If you absolutely don't need to don't use threads and handlers since you might come across a lot of concurrency / deadlock etc issues.
Hope this helps.
Nothing will happen, I ran an algorithm in a async task about 90 hours. Worked fine.
Async Task: seperate a "heavy" task from the UI, for example a download
Service: seperate a task from the App, for example an alarm clock
Related
By referring to Proper way to tackle and resolve "Excessive network usage (background)"
After few months of debugging, we are now able to run all network related code in Foreground service.
However, we are still getting "Excessive network usage (background)" warning in Android Vital.
When foreground service code is executed, a notification UI will always shown in status bar area.
When we "quit" our app, we launch the foreground service, using WorkManager. The WorkManager will return immediately, after foreground service is launched.
public class SyncWorker extends Worker {
#NonNull
#Override
public Result doWork() {
final Intent intent = new Intent(WeNoteApplication.instance(), SyncForegroundIntentService.class);
ContextCompat.startForegroundService(
WeNoteApplication.instance(),
intent
);
return Result.success();
}
}
public class SyncForegroundIntentService extends IntentService {
private static final String TAG = "com.yocto.wenote.sync.SyncIntentService";
public SyncForegroundIntentService() {
super(TAG);
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
final Context context = WeNoteApplication.instance();
NotificationCompat.Builder builder = new NotificationCompat.Builder(...
startForeground(SYNC_FOREGROUND_INTENT_SERVICE_ID, builder.build());
// Perform networking operation within foreground service.
stopForeground(true);
Side note
We don't think we are sending a lot of data. As you can see our latest release, we fall in the lowest range (0 - 5 MB per hour)
Any idea why we're still getting "Excessive network usage (background)"? Apparently, we no longer perform any networking call in background.
We utilize https://developer.android.com/reference/android/app/Service.html#startForeground(int,%20android.app.Notification) and https://developer.android.com/reference/android/content/Context.html#startForegroundService(android.content.Intent)
You are using a Worker to invoke the ForegroundService. From the Worker's documentation:
Worker classes are instantiated at runtime by WorkManager and the
doWork() method is called on a pre-specified background thread (see
Configuration.getExecutor()). This method is for synchronous
processing of your work, meaning that once you return from that
method, the Worker is considered to be finished and will be destroyed. (...) In case the work is preempted for any reason, the same instance of Worker is not reused. This means that doWork() is called exactly once per Worker instance. A new Worker is created if a unit of work needs to be rerun.
A ForegroundService is a Service that you put in the foreground state, that means, the system will not kill the process if it needs CPU or if your app is closed. This and only that.
I wasn't able to find the documentation of Android Vital proving this, so this is only my suspicion, but I'm quite positive this is the case: this means that regardless of the fact that you use ForegroundService or not, Android Vital still counts this as background work.
A proper way to move your app’s mobile-network usage to the foreground is to call DownloadManager with proper visibility setting set (as stated in the link you have provided). Please let me know if that helps - if not we'll try something different. Btw, were you able to narrow down the statistics to a specific API version? (there were some background threading changes in 9.0 and 8.0 so this can also be a clue)
If you're doing this:
When we "quit" our app, we launch the foreground service, using WorkManager. The WorkManager will return immediately, after foreground service is launched.
then you're technically scheduling a worker probably with network constraints every time the user shuts the app.
From the documentation for "Excessive background network usage" link
When an app connects to the mobile network in the background, the app wakes up the CPU and turns on the radio. Doing so repeatedly can run down a device's battery
Thus, even though you're not sending the threshold data of 50MB/ 0.10% of Battery session you're getting this warning cause your app is technically waking up the CPU a lot in the background (for network pings).
Though i'm not sure if this is the problem or not, what you can do is, since even the worker documentation guide says:
WorkManager is intended for tasks that are deferrable—that is, not required to run immediately—and required to run reliably even if the app exits or the device restarts
you can try these:
Scheduling a foreground service as soon as the user shuts the app, instead of scheduling a worker, checking inside the onHandleIntent whether the user is online or not (having a connection and for devices above 7, a flowing internet connection as well).
You can try scheduling a worker to run periodically, lets say every few hours based on your business-side requirements, this could be problem if that's not how you wish to back-up the data, but it serves the real purpose of the worker being a deferred task and not something to be executed immediately.
Not sure about this, never tried, but theoretically looks valid, you can use a Unique Work with a mode called REPLACE to replace the worker and have an initial delay of lets say 30mins, this is a hack, but this will delay running of your worker for 30mins, and in the meanwhile if the user opens and shuts the app again, it will replace the old worker with a new one. This solution has its own drawbacks as well, like sometimes the task wont be scheduled if the user is using the app constantly. But will reduce the total number of times the worker had ran.
Finally, the architecture you're using is valid, the whole thing about using a FG service and a worker to schedule it, just that you're doing it quite often. Source
I was going through Bound Service in Android Developer website. I thought I understood the service enough but I just found another way of connecting service through Using a Messenger class especially for local service. There I got confused. Maybe I got the concept wrong.
Here is my understanding of Android Service. You create a service when
You want to do separate jobs in the background.
You want to make it a separate process.
You want to make it run in a lifecycle that's independent of the component that started it.
Confusion is the first item in the list, the definition of the background. Isn't the background a thread or process? I never thought that it can run on the main thread.
Here is the caution of service in the dev pages about.
Caution: A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work. By using a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the application's main thread can remain dedicated to user interaction with your activities.
Questions
Why does one choose to use service if the service function will anyway run on the main thread?
Do we have to write a service only to block ANR even if the time-consuming job is done in the main thread? Assume the service is only for my application.
Are there any practical cases or reasons to use a service as private and running in the same thread?
Application main thread is not always the UI thread. For example, when Activity is stopped, the onStop() is invoked, hence the UI thread is taken away from that Activity and moved to another Activity within the same or a different application. However it doesn't mean the application is no longer active, it can continue working in the background until it is closed either by OS or by user. Then who keeps it running in the background? It is the main thread and not the UI thread.
What are services
In Android, a Service is an application component that can perform
long-running operations in the background on the UI thread. By
background, it means that it doesn’t have a user interface. A Service
runs on the main thread of the calling Component’s process by default
(and hence can degrade responsiveness and cause ANRs), hence you
should create a new Thread to perform long running operations. A
Service can also be made to run in a completely different process.
Unlike Activity components, Services do not have any graphical
interfaces. Also Broadcast Receivers are for receiving broadcast
messages (broadcast, multicast, unicast) and perform short tasks
whereas Services are meant to do lengthy processing like streaming
music, network transactions, file I/O, interact with databases, etc.
When a Service is started by an application component like an Activity
it runs in the background and keeps running even if the user switches
to another application or the starting component is itself destroyed
Why use service
Services are given higher priority than other Background processes and
hence it’s less likely that Android will terminate it. Although it can
be configured to restart once there is ample resources available
again. You should go through the different processes and their
priority/important level in the documentation on processes and
threads. Assigning them the same priority as foreground activities is
definitely possible in which case it’ll need to have a visible
notification active (generally used for Services playing music).
Use IntentService if you don't want to fiddle with managing threads on your own. Otherwise, use AsyncTasks.
Please read this excellent article to understand more in detail and also read this answer.
Service basically runs in UI thread or main thread.But,if we are going to perform long running operations in service,we need to create a background thread and perform that task.
But why we have to use service?
Now let's think of Music Application.We need songs to be played continuously even if we leave music app.If we use activities,we can't achieve above requirement.So,service helps in these kind of scenarios.Even if the app is not in foreground, service keeps on running and we are able to listen to songs.This is why we use service even though it runs on main thread.
In short, Services runs on the background of the UI thread.
You can perform tasks like client-server authentication or write to a database where the tasks are done in the background with no graphical interface.
But if you're doing a really long processing tasks that could freeze the interface, you use a service on a separate thread.
eg of a Service on a separate thread is IntentService
http://developer.android.com/guide/components/services.html
The page starts off by saying services are used to run long standing tasks in the background. Later in the "caution:", it says they are run on the UI thread, and any intensive work should be done in a separate thread, like the code placed inside IntentService's "onHandleIntent" callback.
If the code in onHandleIntent is the service's long standing task, and that runs in a background thread, why do they say a service runs on the UI thread?
There are multiple reasons for this:
UI thread is the way to work with events and binding, and is easier to understand how to interact with the service. That's usually already done on the UI thread, so it would also be easier to initiate functions on the service.
The service is a component without any UI, so it has less memory being used compared to activities, and also has less chance of having memory leaks compared to activities.
The service can run in the foreground, making it have less chance of being killed when the user goes to other apps.
there is also an IntentService, which has a function (called "onHandleIntent" )that runs only on the background thread, if you wish to perform easy background tasks easily.
Instead of forcing you to work in some way, Google lets you decide how&what to perform on the service.
It has its own lifecycle that isn't affected by UI. It's more affected by resource usage and OS decisions, and by the developer's choice of course.
I'm just approaching Android Services, but i have many doubts. Here there are some questions.
Before starting, notice i have read those pages
Android Services (official)
Bounded Services (official)
plus sone Inner classes theory in my language. Please be patient, i'm still a bit confused.
1) First of all, a Services differentiates itself from an AsyncTask mainly because it continues to run also if the app is paused (i.e. the user is watching another app); AsyncTask is stopped in that cases. Is it ok or am i wrong?
2) A Service runs in the same thread of the activity that started it through startService().
To not affect the Activity's performances, i have to create a separate thread for that Service, for example implementing the Runnable interface. Another method is making a service that extends IntentService, which automatically provides a new thread for the service: a new thread is created on any onHandleIntent() call.
Now, let's look at my concrete problem. I need to create a Service that will be used by many Activities: his task will be to connect to the server DB every 60 seconds and check for news. If a news is found, notify there's a new news (if we are on MainActivity) or show the new news's title (if we are in the news reader). How should i code it?
I have made a MainActivity that instantiate a NewsService and immediately calls startService(). On the other side, i have the NewsService extends IntentService, that (creates a new thread when onHandleIntent is called?) and looks for new news. Is it a bad idea to use a IntentService? I realized it will be very ugly to start the service calling startService() indefinitely.
At the start of this exercize i tought it was a good solution because it automatically creates a new thread and makes Service implementation simple. But now i have some doubts (i can't know if there's a news! How can MainActivity know it? And how to get the title)
This should be done with a normal extends Thread class, that makes an infinite cicle in it's run() method, checking for news every 60 seconds and, if there's a new one, reads the title from remote DB AND update activities buttons/views. Then if the App will be closed by user, the Service will be closed too.
But the problem is that if i istantiate such class it's work will be stopped when the MainActivity is paused or stopped, and other Activities (the NewsReader in this case) cannot get any update because the new thread isn't getting news at the moment. So i need a Service.
I hope it's clear. How should i implement a solution in the right way?
Please highlight everything wrong in my text, i really need to learn :D
You seem to have understood everything correctly.
As to your specific problem, I'd recommend the following:
Use AlarmManager to schedule your service. Don't let the Service run when it does not have to.
Use a Broadcast Intent for new news. All Activities will have to have an inner BroadcastReceiver that listens for the Broadcast intent of the service and reacts accordingly.
Services are a good approach for what you want, they are pretty good to do processes that consume few resources like keeping a daemon in background, they are also good to show notifications without an activity and keep running even if you exit the activity.
When you need to do more heavy operations in your service you can still use an AsyncTask, launch it, execute your operation in another thread and automatically receive the result in your main thread.
If you want to keep the service always running you can use START_STICKY in your Service
#Override
public int onStartCommand(final Intent intent, final int flags,
final int startId) {
// Ensure the service will restart if it dies
return START_STICKY;
}
And you can launch the service doing:
final Intent service = new Intent();
service.setComponent(new ComponentName(YourService.PACKAGE_NAME,
YourService.SERVICE_FULL_NAME));
// Start the service
context.startService(service);
1) First of all, a Services differentiates itself from an AsyncTask
mainly because it continues to run also if the app is paused (i.e. the
user is watching another app); AsyncTask is stopped in that cases. Is
it ok or am i wrong?
This is not correct. AsyncTask is a mechanism for offloading background processing into a separate thread and provides a mechanism for informing the user of progress, error and completion of that background processing. AsyncTask does not stop working if the app is paused. It continues to perform its processing in the background. In general, there is tight coupling between an AsyncTask and the Activity that started it.
A Service, on the other hand, is (generally) completely decoupled from the Activity that started it. A Service has its own lifecycle which is independent of the other activities in the app. Also, services have no UI, so they are not linked to the visual elements of the application and they provide no (direct) mechanisms for visual feedback related to progress, error or completion. This needs to programmed separately.
2) A Service runs in the same thread of the
activity that started it through startService(). To not affect the
Activity's performances, i have to create a separate thread for that
Service, for example implementing the Runnable interface. Another
method is making a service that extends IntentService, which
automatically provides a new thread for the service: a new thread is
created on any onHandleIntent() call.
This isn't correct either. A Service doesn't run on any specific thread. The lifecycle methods of a Service (onCreate(), onStartCommand(), etc.) run on the main (UI) thread, which may or may not be the same thread that called startService(). However, a Service can (and usually does) start other background threads, as many as it needs to, to perform the necessary work.
IntentService is a specific kind of Service which manages one or more worker threads that it uses to perform background processing. You send a "command" to an IntentService and the IntentService then puts your command in a queue. At some point (different implementations in different Android versions behave differently), your "command" is dequeued and processed in a background thread. IntentService stops itself after all the "commands" have been processed. IntentService is often not the best choice for a Service due to the way it behaves.
IntentService is definitely not what you want in your case. You should probably use AlarmManager and set an alarm that starts your Service every minute. When your Service starts, it should create a background thread that contacts your server and checks for news. If there is no news it can just go away. If there is new news, it can either start your Activity to inform the user, or it can send a broadcast Intent which your Activity will see (if it is running),or it could create a Notification which the user can then open whenever he wants to. You need to figure out how you want to determine when the app should stop checking the server. Maybe the user should tell you that he isn't interested anymore, or maybe the Service can recognize that the app isn't running anymore (or hasn't been looked at in more than X hours or whatever). There are lots of ways to do this and it depends on your requirements.
Why do I read in the answer to most questions here a lot about AsyncTask and Loaders but nothing about Services? Are Services just not known very well or are they deprecated or have some bad attributes or something? What are the differences?
(By the way, I know that there are other threads about it, but none really states clear differences that help a developer to easily decide if he is better off using the one or the other for an actual problem.)
In some cases it is possible to accomplish the same task with either an AsyncTask or a Service however usually one is better suited to a task than the other.
AsyncTasks are designed for once-off time-consuming tasks that cannot be run of the UI thread. A common example is fetching/processing data when a button is pressed.
Services are designed to be continually running in the background. In the example above of fetching data when a button is pressed, you could start a service, let it fetch the data, and then stop it, but this is inefficient. It is far faster to use an AsyncTask that will run once, return the data, and be done.
If you need to be continually doing something in the background, though, a Service is your best bet. Examples of this include playing music, continually checking for new data, etc.
Also, as Sherif already said, services do not necessarily run off of the UI thread.
For the most part, Services are for when you want to run code even when your application's Activity isn't open. AsyncTasks are designed to make executing code off of the UI thread incredibly simple.
Services are completely different: Services are not threads!
Your Activity binds to a service and the service contains some functions that when called, blocks the calling thread. Your service might be used to change temperature from Celsius to Degrees. Any activity that binds can get this service.
However AsyncTask is a Thread that does some work in the background and at the same time has the ability to report results back to the calling thread.
Just a thought: A service may have a AsyncTask object!
Service is one of the components of the Android framework, which does not require UI to execute, which mean even when the app is not actively used by the user, you can perform some operation with service. That doesn't mean service will run in a separate thread, but it runs in main thread and operation can be performed in a separate thread when needed.
Examples usages are playing music in background, syncing data with server in backgroud without user interaction etc
AsyncTask on other hand is used for UI blocking tasks to be performed on a separate thread. It is same like creating a new thread and doing the task when all the tasks of creating and maintaining the threads and send back result to main thread are taken care by the AsyncTask
Example usage are fetching data from server, CRUD operations on content resolver etc
Service and asynctasks are almost doing the same thing,almost.using service or a asynctask depends on what is your requirement is.
as a example if you want to load data to a listview from a server after hitting some button or changing screen you better go with a asynctask.it runs parallel with main ui thread (runs in background).for run asynctack activity or your app should on main UI thread.after exit from the app there is no asynctask.
But services are not like that, once you start a service it can run after you exit from the app, unless you are stop the service.like i said it depends on your requirement.if you want to keep checking data receiving or check network state continuously you better go with service.
happy coding.
In few cases, you can achieve same functionality using both. Unlike Async Task, service has it's own life cycle and inherits Context (Service is more robust than an Async Task). Service can run even if you have exited the app. If you want to do something even after app closing and also need the context variable, you will go for Service.
Example: If you want to play a music and you don't want to pause if user leaves the app, you will definitely go for Service.
Comparison of a local, in-process, base class Service✱ to an AsyncTask:
✱ (This answer does not address exported services, or any service that runs in a process different from that of the client, since the expected use cases differ substantially from those of an AsyncTask. Also, in the interest of brevity, the nature of certain specialized Service subclasses (e.g., IntentService, JobService) will be ignored here.)
Process Lifetime
A Service represents, to the OS, "an application's desire to perform a longer-running operation while not interacting with the user" [ref].
While you have a Service running, Android understands that you don't want your process to be killed. This is also true whenever you have an Activity onscreen, and it is especially true when you are running a foreground service. (When all your application components go away, Android thinks, "Oh, now is a good time to kill this app, so I can free up resources".)
Also, depending on the last return value from Service.onCreate(), Android can attempt to "revive" apps/services that were killed due to resource pressure [ref].
AsyncTasks don't do any of that. It doesn't matter how many background threads you have running, or how hard they are working: Android will not keep your app alive just because your app is using the CPU. It has to have some way of knowing that your app still has work to do; that's why Services are registered with the OS, and AsyncTasks aren't.
Multithreading
AsyncTasks are all about creating a background thread on which to do work, and then presenting the result of that work to the UI thread in a threadsafe manner.
Each new AsyncTask execution generally results in more concurrency (more threads), subject to the limitations of the AsyncTasks's thread-pool [ref].
Service methods, on the other hand, are always invoked on the UI thread [ref]. This applies to onCreate(), onStartCommand(), onDestroy(), onServiceConnected(), etc. So, in some sense, Services don't "run" in the background. Once they start up (onCreate()), they just kinda "sit" there -- until it's time to clean up, execute an onStartCommand(), etc.
In other words, adding additional Services does not result in more concurrency. Service methods are not a good place to do large amounts of work, because they run on the UI thread.
Of course, you can extend Service, add your own methods, and call them from any thread you want. But if you do that, the responsibility for thread safety lies with you -- not the framework.
If you want to add a background thread (or some other sort of worker) to your Service, you are free to do so. You could start a background thread/AsyncTask in Service.onCreate(), for example. But not all use cases require this. For example:
You may wish to keep a Service running so you can continue getting location updates in the "background" (meaning, without necessarily having any Activities onscreen).
Or, you may want to keep your app alive just so you can keep an "implicit" BroadcastReceiver registered on a long-term basis (after API 26, you can't always do this via the manifest, so you have to register at runtime instead [ref]).
Neither of these use cases require a great deal of CPU activity; they just require that the app not be killed.
As Workers
Services are not task-oriented. They are not set up to "perform a task" and "deliver a result", like AsyncTasks are. Services do not solve any thread-safety problems (notwithstanding the fact that all methods execute on a single thread). AsyncTasks, on the other hand, handle that complexity for you.
Note that AsyncTask is slated for deprecation. But that doesn't mean your should replace your AsyncTasks with Services! (If you have learned anything from this answer, that much should be clear.)
TL;DR
Services are mostly there to "exist". They are like an off-screen Activity, providing a reason for the app to stay alive, while other components take care of doing the "work". AsyncTasks do "work", but they will not, in and of themselves, keep a process alive.