- Android Services — Tutorial
- 1. Android Services
- 1.1. What are services?
- 1.2. Services and background processing
- 1.3. Platform service and custom services
- 1.4. Starting and defining custom services
- 1.5. Foreground services
- 2. Defining custom services
- 2.1. Implementation and declaration
- 2.2. Start a service
- 2.3. Service start process and execution
- 2.4. Service restart behavior
- 2.5. Stopping a service
- 3. IntentServices for one time tasks
- 4. Communication with services
- 4.1. Options for communication
- 4.2. Using Intent data
- 4.3. Using receiver
- 4.4. Activity binding to local service
- 4.5. Handler and ResultReceiver or Messenger
- 4.6. AIDL for services in a different process
- 5. Scheduling service
- 6. Exercise: Using services and service communication
- 7. Exercise: Define and consume local service
- Creating Android Services
- Android Services Overview
- Background Execution Limits in Android 8.0
Android Services — Tutorial
Using styles and themes in Android. Developing own services and using system services in Android. This tutorial describes how to create and consume Android services.
1. Android Services
1.1. What are services?
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 potentially long running operations, i.e., Internet downloads, checking for new data, data processing, updating content providers and the like.
Services run with a higher priority than inactive or invisible activities and therefore it is less likely that the Android system terminates them. Services can also be configured to be restarted if they get terminated by the Android system once sufficient system resources are available again.
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.
1.2. Services and background processing
By default, a service runs in the same process as the main thread of the application.
Therefore, you need to use asynchronous processing in the service to perform resource intensive tasks in the background. A commonly used pattern for a service implementation is to create and run a new Thread in the service to perform the processing in the background and then to terminate the service once it has finished the processing.
Services which run in the process of the application are sometimes called local services .
1.3. Platform service and custom services
The Android platform provides and runs predefined system services and every Android application can use them, given the right permissions. These system services are usually exposed via a specific Manager class. Access to them can be gained via the getSystemService() method. The Context class defines several constants for accessing these services.
An Android application can, in addition to consuming the existing Android platform services, define and use new services. Defining your custom services allows you to design responsive applications. You can fetch the application data via it and once the application is started by the user, it can present fresh data to the user.
1.4. Starting and defining custom services
Custom services are started from other Android components, i.e., activities, broadcast receivers and other services.
1.5. Foreground services
A foreground service is a service that should have the same priority as an active activity and therefore should not be killed by the Android system, even if the system is low on memory. A foreground service must provide a notification for the status bar, which is placed under the «Ongoing» heading, which means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.
2. Defining custom services
2.1. Implementation and declaration
A service needs to be declared in the AndroidManifest.xml file and the implementing class must extend the Service class or one of its subclasses.
The following code shows an example for a service declaration and its implementation.
2.2. Start a service
An Android component (service, receiver, activity) can trigger the execution of a service via the startService(intent) method.
Alternatively, you can also start a service via the bindService() method call. This allows you to communicate directly with the service. We discuss that later.
2.3. Service start process and execution
If the startService(intent) method is called and the service is not yet running, the service object is created and the onCreate() method of the service is called.
Once the service is started, the onStartCommand(intent) method in the service is called. It passes in the Intent object from the startService(intent) call.
If startService(intent) is called while the service is running, its onStartCommand() is also called. Therefore your service needs to be prepared that onStartCommand() can be called several times.
What if you call this method twice in your code? Do you have to worry about synchronizing the onStartCommand() method call? No, this method is called by the Android system in the main user interface thread, therefore it cannot be called simultaneously from two different threads. |
A service is only started once, no matter how often you call the startService() method.
2.4. Service restart behavior
In its onStartCommand() method call, the service returns an int which defines its restart behavior in case the service gets terminated by the Android platform. You can use the constants, the most common options are described by the following table.
Option | Description |
---|---|
You can check if the service was restarted via the Intent.getFlags() method. START_FLAG_REDELIVERY (in case the service was started with Service.START_REDELIVER_INTENT) or START_FLAG_RETRY (in case the service was started with Service.START_STICKY) is passed. |
2.5. Stopping a service
You stop a service via the stopService() method. No matter how frequently you called the startService(intent) method, one call to the stopService() method stops the service.
A service can terminate itself by calling the stopSelf() method. This is typically done if the service finishes its work.
3. IntentServices for one time tasks
You can also extend the IntentService class for your service implementation.
The IntentService is used to perform a certain task in the background. Once done, the instance of IntentService terminates itself automatically. An example for its usage would be downloading certain resources from the internet.
The IntentService class offers the onHandleIntent() method which will be asynchronously called by the Android system.
4. Communication with services
4.1. Options for communication
There are several possibilities for a communication between an activity and a service. The following description discusses the possible approaches and provides recommendation which to use.
4.2. Using Intent data
In a simple scenario no direct communication is required. The service receives the intent data from the starting Android component and performs its work. No notification is necessary. For example, in case the service updates a content provider, the activity is notified by the content provider and no extra step in the service is necessary. This approach works for local and services running in their own process.
4.3. Using receiver
You can use broadcasts and registered receivers for the communication. For example, your activity can register a broadcast receiver for an event and the service sends outs corresponding events. This is a very typical scenario, in which the service need to signal to the activity that his processing has finished.
This communication flow is depicted in the following graphic.
This approach works for local and services running in their own process.
Android provides the LocalBroadcastManager class in the support library v4. This is a helper class to register for and send broadcasts of Intents to local objects within your process. This approach improves security as the broadcast events are only visible within your process and is faster than using standard events.
4.4. Activity binding to local service
If the service is started in the same process as the activity, the activity can directly bind to the service. This is a relatively simple and efficient way to communicate and recommended for activities which need to have a fast communication layer with the service.
This approach works for local services.
4.5. Handler and ResultReceiver or Messenger
If the service should be communicating back to the activity, it can receive an object of type Messenger via the Intent data it receives from the activity. If the Messenger is bound to a Handler in the activity, the service can send objects of type Message to the activity.
A Messenger is parcelable, which means it can be passed to another process and you can use this object to send Messages to the Handler in the activity.
Messenger also provides the method getBinder() which allows passing a Messenger to the activity. The activity can therefore send Messages to the service.
This approach works for local services running in their own process.
4.6. AIDL for services in a different process
To bind to a service which runs in a different process, you need to use Inter Process Communication (IPC) to community your the data. To do so, you need to create a AIDL file which looks similar to a Java interface, but ends with the .aidl file extension and is only allowed to extend other AIDL files.
This approach is required if you need to bind to a service running in another process, i.e., if your service is consumed by other Android applications.
You can find more information about this approach in the Android developer documentation about AIDL.
5. Scheduling service
See https://www.vogella.com/tutorials/AndroidTaskScheduling/article.html — Android task scheduling to learn how to schedule service periodically.
6. Exercise: Using services and service communication
The following example demonstrates how to use a service to download a file from the Internet based on a button click from an activity. Once done, the service notifies the activity via a broadcast receiver that the download is complete.
In this exercise you use the IntentService class, as this class provides automatic background processing.
Create a new project called com.vogella.android.service.receiver with the activity called MainActivity.
Create the following class for the service.
Add this class to the AndroidManifest.xml file. Also add the permission to write to external storage and to access the Internet. The resulting AndroidManifest.xml file should look similar to the following listing.
Change the layout file of your activity to the following.
Change MainActivity to the following.
If you run your example and press the button, the download should be performed by the service. Once done, the user interface is updated and a Toast with the file name is shown.
Change the setting so that the service runs in its own process. Ensure that the application still works, as broadcast receivers are received across process boundaries.
7. Exercise: Define and consume local service
This exercise demonstrates how to bind to a local service from an activity.
The activity binds itself to the service to access its data.
Create a new project called com.vogella.android.localservice with the activity called MainActivity using the Empty Activity template.
Create the following LocalWordService class.
Register your service in the AndroidManifest.xml file.
Change the layout file of the activity similar to the following example.
Change your activity class to the following code.
Run your application. Via your buttons you can update your list or tell the service to fetch more data.
Источник
Creating Android Services
This guide discusses Xamarin.Android services, which are Android components that allow work to be done without an active user interface. Services are very commonly used for tasks that are performed in the background, such as time consuming calculations, downloading files, playing music, and so on. It explains the different scenarios that services are suited for and shows how to implement them both for performing long-running background tasks as well as for providing an interface for remote procedure calls.
Android Services Overview
Mobile apps are not like desktop apps. Desktops have copious amounts of resources such as screen real estate, memory, storage space, and a connected power supply, mobile devices do not. These constraints force mobile apps to behave differently. For example, the small screen on a mobile device typically means that only one app (i.e. Activity) is visible at a time. Other Activities are moved to the background and pushed into a suspended state where they cannot perform any work. However, just because an Android application is in the background does not mean that it is impossible for app to keep working.
Android applications are made up of at least one of the following four primary components: Activities, Broadcast Receivers, Content Providers, and Services. Activities are the cornerstone of many great Android applications because they provide the UI that allows a user to interact with the application. However, when it comes to performing concurrent or background work, Activities are not always the best choice.
The primary mechanism for background work in Android is the service. An Android service is a component that is designed to do some work without a user interface. A service might download a file, play music, or apply a filter to an image. Services can also be used for interprocess communication (IPC) between Android applications. For example one Android app might use the music player service that is from another app or an app might expose data (such as a person’s contact information) to other apps via a service.
Services, and their ability to perform background work, are crucial to providing a smooth and fluid user interface. All Android applications have a main thread (also known as a UI thread) on which the Activities are run. To keep the device responsive, Android must be able to update the user interface at the rate of 60 frames per second. If an Android app performs too much work on the main thread, then Android will drop frames, which in turn causes the UI to appear jerky (also sometimes referred to as janky). This means that any work performed on the UI thread should complete in the time span between two frames, approximately 16 milliseconds (1 second every 60 frames).
To address this concern, a developer may use threads in an Activity to perform some work that would block the UI. However, this could cause problems. It is very possible that Android will destroy and recreate the multiple instances of the Activity. However, Android will not automatically destroy the threads, which could result in memory leaks. A prime example of this is when the device is rotated – Android will try to destroy the instance of the Activity and then recreate a new one:
This is a potential memory leak – the thread created by the first instance of the Activity will still be running. If the thread has a reference to the first instance of the Activity, this will prevent Android from garbage collecting the object. However, the second instance of the Activity is still created (which in turn might create a new thread). Rotating the device several times in rapid succession may exhaust all the RAM and force Android to terminate the entire application to reclaim memory.
As a rule of thumb, if the work to be performed should outlive an Activity, then a service should be created to perform that work. However, if the work is only applicable in the context of an Activity, then creating a thread to perform the work might be more appropriate. For example, creating a thumbnail for a photo that was just added to a photo gallery app should probably occur in a service. However, a thread might be more appropriate to play some music that should only be heard while an Activity is in the foreground.
Background work can be broken down into two broad classifications:
- Long Running Task – This is work that is ongoing until explicitly stopped. An example of a long running task is an app that streams music or that must monitor data collected from a sensor. These tasks must run even though the application has no visible user interface.
- Periodic Tasks – (sometimes referred to as a job) A periodic task is one that is of relatively short in duration (several seconds) and is run on a schedule (i.e. once a day for a week or perhaps just once in the next 60 seconds). An example of this is downloading a file from the internet or generating a thumbnail for an image.
There are four different types of Android services:
Bound Service – A bound service is a service that has some other component (typically an Activity) bound to it. A bound service provides an interface that allows the bound component and the service to interact with each other. Once there are no more clients bound to the service, Android will shut the service down.
IntentService – An IntentService is a specialized subclass of the Service class that simplifies service creation and usage. An IntentService is meant to handle individual autonomous calls. Unlike a service, which can concurrently handle multiple calls, an IntentService is more like a work queue processor – work is queued up and an IntentService processes each job one at a time on a single worker thread. Typically, an IntentService is not bound to an Activity or a Fragment.
Started Service – A started service is a service that has been started by some other Android component (such as an Activity) and is run continuously in the background until something explicitly tells the service to stop. Unlike a bound service, a started service does not have any clients directly bound to it. For this reason, it is important to design started services so that they may be gracefully restarted as necessary.
Hybrid Service – A hybrid service is a service that has the characteristics of a started service and a bound service. A hybrid service can be started by when a component binds to it or it may be started by some event. A client component may or may not be bound to the hybrid service. A hybrid service will keep running until it is explicitly told to stop, or until there are no more clients bound to it.
Which type of service to use is very dependent on application requirements. As a rule of thumb, an IntentService or a bound service are sufficient for most tasks that an Android application must perform, so preference should be given to one of those two types of services. An IntentService is a good choice for «one-shot» tasks, such as downloading a file, while a bound service would be suitable when frequent interactions with an Activity/Fragment is required.
While most services run in the background, there is a special sub-category known as a foreground service. This is a service that is given a higher priority (compared to a normal service) to perform some work for the user (such as playing music).
It is also possible to run a service in its own process on the same device, this is sometimes referred to as a remote service or as an out-of-process service. This does require more effort to create, but can be useful for when an application needs to share functionality with other applications, and can, in some cases, improve the user experience of an application.
Background Execution Limits in Android 8.0
Starting in Android 8.0 (API level 26), an Android application no longer have the ability to run freely in the background. When in the foreground, an app can start and run services without restriction. When an application moves into the background, Android will grant the app a certain amount of time to start and use services. Once that time has elapsed, the app can no longer start any services and any services that were started will be terminated. At this point it is not possible for the app to perform any work. Android considers an application to be in the foreground if one of the following conditions are met:
- There is a visible activity (either started or paused).
- The app has started a foreground service.
- Another app is in the foreground and is using components from an app that would be otherwise in the background. An example of this is if Application A, which is in the foreground, is bound to a service provided by Application B. Application B would then also be considered in the foreground, and not terminated by Android for being in the background.
There are some situations where, even though an app is in the background, Android will wake up the app and relax these restrictions for a few minutes, allowing the app to perform some work:
- A high priority Firebase Cloud Message is received by the app.
- The app receives a broadcast.
- The application receives and executes a PendingIntent in response to a Notification.
Existing Xamarin.Android applications may have to change how they perform background work to avoid any issues that might arise on Android 8.0. Here are some practical alternatives to an Android service:
- Schedule work to run in the background using the Android Job Scheduler or the Firebase Job Dispatcher – These two libraries provide a framework for applications to segregate background work in to jobs, a discrete unit of work. Apps can then schedule the job with the operating system along with some criteria about when the job can run.
- Start the service in the foreground – a foreground service is useful for when the app must perform some task in the background and the user may need to periodically interact with that task. The foreground service will display a persistent notification so that the user is aware that the app is running a background task and also provides a way to monitor or interact with the task. An example of this would be a podcasting app that is playing back a podcast to the user or perhaps downloading a podcast episode so that it can be enjoyed later.
- Use a high priority Firebase Cloud Message (FCM) – When Android receives a high priority FCM for an app, it will allow that app to run services in the background for a short period of time. This would be a good alternative to having a background service that polls an app in the background.
- Defer work for when the app comes into the foreground – If none of the previous solutions are viable, then apps must develop their own way to pause and resume work when the app comes to the foreground.
Источник