Android-service components

Source: Internet
Author: User

Reprint please indicate source: http://blog.csdn.net/goldenfish1919/article/details/40381109

Original: http://developer.android.com/guide/components/services.html

Service is one of the four components of Android, it does not have a UI interface and can perform long operations in the background. Other components can start a service,service and will continue running in the background, regardless of whether the user has switched to another application. In addition, other components can be bound to the service, interact with the service, and even perform cross-process operations (IPC). For example, a service can process network requests in the background, play music, perform file I/O, or interact with content provider.

There are two types of service:
Started
When other components are started by calling StartService (), the service is "Started". Once started, the service runs indefinitely in the background, even if the component that started it has been destroyed. Typically, the Started service will only do a single operation and will not return a value to the caller. For example: it can be downloaded through the network or upload files. When the operation is over, the service will manually stop itself.

Bound
The service is "bound" when other components are bound to the service by calling Bindservice (). The bound service provides a client/server interface that allows components to interact with the service, send requests, get results, and even do cross-process operations. Bound service only survives when other components are bound to it, multiple components can be bound to a service at the same time, but when all components are simultaneously unbound, the service is destroyed.

Although this document discusses these two types of service separately, your service can support both types, and the service can be started (infinite run) while also allowing binding. This only depends on whether you have implemented the following callback: Onstartcommand () allows other components start a service,onbind () to allow the service to be bound.

Regardless of whether your service is started or bound, other components of the application can use the service (and even other applications). Just as other components can use an activity, start it with intent. However, you can also declare the service to be private in the manifest file, which prevents other apps from accessing it.


For more information, refer to the section "declaring a service in a manifest file" (http://developer.android.com/guide/components/services.html#Declaring).

Note: The service is running on the main thread of the host process, and the service does not create its own thread and will not run in a separate process unless you specify it. This means that if your service is doing something that consumes CPU or is blocking (for example, playing MP3 or a network request), you need to manually create a new thread inside the service to do so. By using separate threads, the risk of ANR is reduced, allowing the main thread to focus on UI actions.

Service Base

To create a service, you must create a subclass of service (or service subclass). In your implementation, you will rewrite some callback methods, which are used to handle some of the critical life cycles of the service, and provide a mechanism for the component to bind to the service, if appropriate.

The most important callbacks to rewrite are:

Onstartcommand ()

The system calls this method when another component launches the service by calling StartService (). Once this method starts executing, the service starts up and runs indefinitely in the background. If you override this method, you are also responsible for destroying the service by calling Stopself () or StopService () after the service has finished working. (You don't need to implement this method if you just want to provide bindings)

Onbind ()
The system calls this method when other components are bound to the service by calling Bindservice () (for example, RPC). When implementing this method, it is necessary to provide the client with an interface to interact with the service by returning a ibinder. This method is generally implemented, but if you do not allow binding, you can return null.

OnCreate ()
When the service is first started, the system calls this method and executes only once (before calling Onstartcommand () or Onbind ()). If the service is already running, this method will not be called.

OnDestroy ()
The system calls this method when the service is no longer being used or is being destroyed. Your service will implement this method to do some cleanup of resources, such as: threads, listening, broadcasting receivers and so on. This is the last callback received by the service.

If a component starts a service through StartService () (which causes the system to call Onstartcommand ()), the service runs until it calls Stopself () or another component calls StopService () To stop it.

If a component starts a service through Bindservice () (Onstartcommand () is not called), the service only survives on the component that is bound to it. Once the service is unbound from all clients, it will be terminated by the system.

The Android system will only force the service to be killed when the system is out of memory, and the system must be able to provide system resources to the activity that has the user focus.
If the service is bound to an activity that has user focus, it is likely not to be killed.
If the service is declared to be running in the foreground, it is generally not killed.
In other cases, if the service is started and is long running, the system will be placed in the back of the background task list over time and it will become easy to kill.
If your service is started, you have to allow it to gracefully handle the restart of the system.
If the system kills your service, once the resource is available, the system will immediately restart the service that was killed (which also depends on the return value of Onstartcommand ().
For more information on how the system might kill the service, refer to: Processes and Threads (http://developer.android.com/guide/components/processes-and-threads.html).

In the following sections, you will learn how to create various types of service, and how to use the service in other components.

Declaring the service in the manifest file

Similar to activity (there are other components), you must declare all the service in the manifest file.

To declare a service, add the <service> element as a sub-element of <application>, such as:

<manifest ... >
...
<application ... >
<service android:name= ". Exampleservice "/>
...
</application>
</manifest>

For more information on the Manifest statement service, refer to <service> elements Daquan (http://developer.android.com/guide/topics/manifest/ service-element.html).

The <service> element also has many other properties that can be used to define the permissions to start the service or the process that the service runs. The Android:name property is unique, and it specifies the class name of the service. Once you've published your app, you shouldn't have to change the name again. If you modify it, the code that uses explicit intent to start or bind service has a crash risk.

To ensure that your application is secure, always use explicit intent when start or bind a service, and do not intent filter to the service statement. If it is important to allow an ambiguous way to start the service, you can provide the service with a intent filter that excludes some component names. However, you must set the Pachage for intent with setpackage (), which provides sufficient certainty for the target service to invoke.

In addition, you can also use the introduction of the Android:exported property and set its value to false to ensure that your service is only available to your app. This effectively prevents other applications from starting your service, even with explicit intent.

Create a started Service

If another component starts the service by calling StartService (), the service is a started service, which causes the system to call Servicve's Onstartcommand () method.

When the service is started, its life cycle is independent of the life cycle of the component that initiated it, and the service can run indefinitely in the background, even if the component that initiated it has been destroyed. In this case, when its task is completed, the service needs to call Stopself () to stop itself, and the other component can call StopService () to stop the service.

Components of an application such as activity can start a service by calling StartService (), and passing a intent,intent to the service specifies the service to start and the data that is passed to the service for use. The service will receive this intent in the Onstartcommand () method.

For example, if an activity needs to save data to a database on the network, activity can start a service and pass it through intent to the service to save the data. The service receives intent in the Onstartcommand () method, connects to the network, and does the database operation. When the operation is completed, the service will stop itself and the servive will be destroyed.

Note: The service is running in the same process as the app, which is run on the main thread of the app by default. Therefore, if the service does some time-consuming or blocking operations when the user interacts with the application, the service slows down the performance of the activity. To avoid affecting the performance of your application, you need to open a new thread within the service.

In general, you can create a started service by inheriting two classes:

One is to inherit the service
Service is the base class for all service. When you inherit this class, you need to open a new thread within the service to do the heavy lifting, because the service defaults to the application's main threads, and it affects the performance of the application.

The other one is to inherit Intentservice.
It is a subclass of service that uses a worker thread internally to handle all requests, one at a time. This is the best option if your service does not need to synchronize and process multiple requests. All you have to do is implement the Onhandleintent () method, which will receive the requested intent, so you can do the background task.

The following sections describe how to implement a service with these two classes.

Inheriting the Intentservice class

Because most started service do not need to handle concurrent requests, using Intentservice may be the best solution.

Intentservice will do the following things:

(1) Create a default worker thread that is used to execute the intent that is passed to Onstartcommand () and is independent of the main thread of the application.
(2) Create a task queue. Pass only one intent to onhandleintent () method at a time, so there's no need to worry about multithreading.
(3) When all requests have been processed, the service will stop automatically, so you do not need to call stopself ().
(4) The default implementation of Onbind () is provided, and the method returns NULL.
(5) The default implementation of Onstartcommand () is provided, and the intent is sent to the work queue and sent to Onhandleintent ().

All of this, all you have to do is implement Onhandleintent () to complete the client's work (you can also provide a constructor for the service, of course).

Here is an example that implements the Intentservice:

public class Hellointentservice extends Intentservice {/** * A constructor are required, and must call the Super Intent   Service (String) * constructor with a name for the worker thread.  */Public Hellointentservice () {Super ("Hellointentservice"); }/** * The Intentservice calls this method from the default worker thread with a * the intent that started the service .   When this method returns, Intentservice * stops the service, as appropriate.  */@Override protected void Onhandleintent (Intent Intent) {//Normally we would do some work here, like download a      File.      For our sample, we just sleep for 5 seconds.      Long endTime = System.currenttimemillis () + 5*1000; while (System.currenttimemillis () < EndTime) {synchronized (this) {try {wait (              Endtime-system.currenttimemillis ()); } catch (Exception e) {}}}}}

That's all you have to do: a constructor and implementation onhandleintent ().

If you want to overwrite other callbacks such as OnCreate (), Onstartcommand (), or OnDestroy (), be sure to remember to invoke the implementation of the parent class so that Intentservice can correctly handle the life cycle of the worker thread.

For example, Onstartcommand () must return to the default implementation (as intent is passed to Onhandleintent ()).

@Overridepublic int Onstartcommand (Intent Intent, int flags, int startid) {    Toast.maketext (this, "service starting", Toast.length_short). Show ();    Return Super.onstartcommand (Intent,flags,startid);}

Except for Onhandleintent (), the only function that does not need to call the parent class is Onbind () (this method is required only if the binding is not allowed).

In the next section, you'll see how you can inherit different base classes to achieve the same functionality, with a bit more code, but it can be useful if you want to handle concurrent requests.

Inheriting the service class

As seen in the previous section, using Intentservice makes it easy to implement a started service. However, if your service needs to handle multithreading (instead of processing requests through a work queue), you can inherit the service class to handle intent.

As a comparison, the following example is a implementation of the service class to complete the same function as above using Intentservice, that is, to each request, the worker thread is used to complete the work, only one request is processed at a time.

public class HelloService extends Service {private Looper mservicelooper;  Private Servicehandler Mservicehandler; Handler that receives messages from the thread private final class Servicehandler extends Handler {public Servic      Ehandler (Looper Looper) {super (Looper); } @Override public void Handlemessage (Message msg) {//Normally we would does some work here, like DOWNL          Oad a file.          For our sample, we just sleep for 5 seconds.          Long endTime = System.currenttimemillis () + 5*1000;                      while (System.currenttimemillis () < EndTime) {synchronized (this) {try {                  Wait (Endtime-system.currenttimemillis ()); } catch (Exception e) {}}}//Stop the service using the Startid, so th      At we don ' t stop//The service in the middle of handling another job stopself (MSG.ARG1); }} @Override PuBlic void OnCreate () {//Start up the thread running the service.  Note that we create a//separate thread because the service normally runs in the process ' s//main thread, which we  Don ' t want to block.    We also make it//background The cpu-intensive work won't disrupt our UI.    Handlerthread thread = new Handlerthread ("Servicestartarguments", Process.thread_priority_background);    Thread.Start ();    Get the Handlerthread ' s Looper and use it for our Handler Mservicelooper = Thread.getlooper ();  Mservicehandler = new Servicehandler (mservicelooper); } @Override public int onstartcommand (Intent Intent, int flags, int. Startid) {Toast.maketext (this, "service Starti      Ng ", Toast.length_short). Show (); For per start request, send a message to start a job and deliver the//start ID so we know which request we ' re s      Topping when we finish the job Message msg = Mservicehandler.obtainmessage ();      MSG.ARG1 = Startid; MsErvicehandler.sendmessage (msg);  If we get killed, after returning from here, restart return start_sticky;  } @Override Public IBinder onbind (Intent Intent) {//We don ' t provide binding, so return null return null;  } @Override public void OnDestroy () {Toast.maketext (this, "service-Done", Toast.length_short). Show (); }}

As you can see, there is a lot of extra work to do compared to using Intentservice.

However, because you are processing requests in Onstartcommand (), you can handle multiple requests concurrently. This is beyond the scope of this example. But if you need to, you can create a thread for each request and execute it immediately (instead of waiting for the previous request to finish).

It is important to note that Onstartcommand () must return an integer return value. The return value describes how the service is handled by the system when it is restart after the service has been killed (as discussed earlier, Intentservice will do this for you, and you can modify it, of course). The return value must be some of the following constants:

Start_not_sticky
If Onstartcommand () returns, the service will not be recreated when the system kills Service,restart, unless there is pending intent to send. This is the safest way to avoid running unnecessary service, and the app can simply restart any unfinished task.

Start_sticky
If Onstartcommand () returns, the service is recreated when the system kills Service,restart, and then Onstartcommand () is called, but the final intent is not sent again. Instead, the system calls Onstartcommand () with a null intent, unless there is a pending intent to start the service, in which case the intent is passed in. This is very suitable for media players (or similar service) because they do not execute commands, just run indefinitely and wait for new tasks.

Start_redeliver_intent

If Onstartcommand () returns after the system kills Service,restart, the service is recreated, then Onstartcommand () is called, and the final intent is sent again. Pending intents will be sent sequentially, which is suitable for situations that need to be awakened immediately, such as downloading files.

For more information on return values, refer to the documentation for each constant.

Start Service

You can start the service by passing intent (specifying the service to start) in the activity, which is the other component, by giving StartService (). The Android system invokes the service's Onstartcommand () method and then passes the intent in (the direct call to Onstartcommand () is prohibited).

For example, activity can start the example service (HelloService) in the previous section with explicit intent in StartService ().

Intent Intent = new Intent (this, helloservice.class); StartService (Intent);

The StartService () method returns immediately, and the Android system invokes the service's Onstartcommand () method. If the service has not been executed, the system will first call OnCreate () and then call Onstartcommand ().

If the service does not provide a binding, the intent passed in by the StartService () method is the only way to communicate with external components. However, if you want the service to send the results out, the client that started the service can create a broadcast pendingintent, (with Getbroadcast ()), and pass the pendingintent to the service. The service can use broadcasts to deliver results.

Multiple Onstartcommand () calls to the service are caused by several requests to start the service. However, only one request to stop the service is required to stop the service.

Shut down service

The started service must manage its own lifecycle. That is, the system does not stop or destroy the service unless it is to free system resources, and the service will continue to run after Onstartcommand () returns. Therefore, the service must call Stopself () to stop itself or other components from calling StopService () to stop the service.

Once the service is stopped with stopself () or StopService (), the system will destroy the service as soon as possible.

However, if your service is processing requests concurrently in Onstartcommand (), you should not stop the service after you have processed a request, because you may receive a new request (stopping the service at the end of the first request will also stop the second request). To avoid such a thing, you can use stopself (int) to ensure that the request to stop the service is always based on the most recent request. That is, when you call stopself (int), you pass the start request ID of the corresponding stop request (Startid is passed to Onstartcommand ()). Then, if the service receives a boot request before calling stopself (int), the ID does not match and the service does not stop.

Note: Stopping the service when the service is done is important to avoid wasting system resources and saving power. If needed, other components can call StopService () to stop the service. The service with the binding enabled, and if a onstartcommand () call is received, it is also necessary to manually stop the service.

To learn more about the service lifecycle, see the section under "Managing the life cycle of a service."

Create bound Service

The bound service allows the application's component call Bindservice () to bind to the service, in order to create a long-existing connection (typically not allowing the component to call StartService () to start).

You should create a bound service when you want to interact with the service from activity or other components, or through some of the features of the IPC burst application to other applications.

To create a bound service, you must implement the Onbind () callback and return IBinder, which defines the interface to service traffic. Other components can call Bindservice () to retrieve the interface and then invoke the service's method. The service only survives on the component it is bound to, so when there is no component binding, the system destroys it (you do not need to stop the bound service as you would stop the started service).

To create a bound service, the first thing to do is to define the interface that the client interacts with the service. The interface between the service and the client must be an implementation of IBinder, and the service must be returned in the Onbind () callback, and once the client receives the IBinder, it can interact with the service through the interface.

Multiple clients can bind to the same service at the same time, and when a client interacts with the service, it calls Unbindservice () to unbind. If no client is bound to the service, the system will destroy the service.

There are many ways to implement bound service, and the general implementation is more complex than the started service, so bound service will be in a separate article (http://developer.android.com/guide/ components/bound-services.html) in the discussion.

Send notification to User

Once run, the service can send a reminder event to the user using the popup notification or the status bar notification.

A pop-up reminder is a message prompt that appears on top of the current window and then disappears, and the status bar reminds you that an icon is available in the status bar's message, and the user can choose to do something (such as starting an activity).

In general, when a background task is completed, a status bar alert is the best way to do it (for example, a file download is complete), and then the user can do some action. When a user selects a reminder in the expanded view, the reminder can open an activity (such as a view that jumps to a downloaded file).

Front Desk running Service


Front-desk service is considered user-aware and is not a candidate to be killed when the system memory is low. The front service must be alerted in the status bar and placed under the "in Progress" header, which means that the reminder will not disappear unless the service is stopped or removed from the foreground.

For example, the service's music player should run in the foreground, because the user is clearly aware of its operation, the status bar reminder can indicate the song currently playing, and allows the user to jump to the activity of the music player to do some interaction.

Having the service run in the foreground requires calling the Startforeground () method. This method accepts 2 parameters, a unique integer that identifies the reminder, and a reminder for the status bar. Like what:

Notification Notification = new Notification (R.drawable.icon, GetText (R.string.ticker_text), System.currenttimemillis ()); Intent notificationintent = new Intent (this, exampleactivity.class); Pendingintent pendingintent = pendingintent.getactivity (this, 0, notificationintent, 0); Notification.setlatesteventinfo (This, GetText (R.string.notification_title), GetText (r.string.notification_ message), pendingintent); Startforeground (ongoing_notification_id, NOTIFICATION);

Note: The ID must not be 0.

To remove a service from the foreground, you need to call Stopforeground (). This method receives a Boolean parameter that indicates whether to remove the reminder from the status bar. This method does not stop the service, but if you want to stop it while the service is running in the foreground, the reminder will be removed.

Manage the service life cycle

The service life cycle is much simpler than the life cycle of the activity. However, you need to pay more attention to the creation and destruction of the service because the service can run in the background without the user's knowledge.

The service life cycle-from creation to destruction-follows a different form in the following 2:

(1) Started service
When the other component calls StartService () the service is created and then runs indefinitely, it must manually call Stopself () to stop itself. Other components can call StopService () to stop it. When the service is stopped, the system destroys it.


(2) Bound service
When the other component (client) calls Bindservice (), the service is created, and the client interacts with the service through the IBinder interface. The client can call Unbindservice () to turn off the connection to the service. Multiple clients can connect to a service at the same time, and when all clients are unbound, the system destroys the service (the service does not need to be manually stopped).

These two forms are not entirely independent. In other words, you can bind to a started service that starts with StartService (). For example, the background music service can be started by passing the intent of the song to be played by StartService (), and then, when the user wants to do something to the player or to get information about the current song, You can bind activity through Bindservice () to the service. In this case, StopService () or stopself () does not stop the service until all the clients have been untied.

Implementing Life cycle Callbacks

Similar to Activity,service also has the life of the callback function allows you to monitor the status of the service and do something at the right time.


The following example shows each life cycle function:

public class Exampleservice extends Service {int mstartmode;      Indicates how to behave if the service is killed IBinder Mbinder; Interface for clients this bind Boolean mallowrebind; Indicates whether Onrebind should be used @Override public void onCreate () {//The service is being creat ED} @Override public int onstartcommand (Intent Intent, int flags, int. Startid) {//the service is Starti    Ng, due to a call to StartService () return mstartmode;        } @Override Public IBinder onbind (Intent Intent) {//A client are binding to the service with Bindservice ()    return mbinder;        } @Override public boolean onunbind (Intent Intent) {//All clients has unbound with Unbindservice ()    return mallowrebind;        } @Override public void Onrebind (Intent Intent) {//A client are binding to the service with Bindservice (), After Onunbind () have already been called} @Override   public void OnDestroy () {//The service was no longer used and is being destroyed}} 

Note: Unlike activity's lifecycle callbacks, these callbacks do not require the implementation of the parent class to be called.

By implementing these methods, you can monitor 2 loops within the service life cycle:

(1) The full life cycle of the service is returned from the call OnCreate () to OnDestroy (). Similar to activity, the service is initialized in OnCreate () and frees up resources in OnDestroy (). For example, the music player service can create a music-playing thread in OnCreate () and stop the thread in OnDestroy (). All service calls OnCreate () and OnDestroy (), regardless of whether the service is created with StartService () or Bindservice ().

(2) The time of the service's activity starts with the call to Onstartcommand () or Onbind (). In this correspondence, the two methods will handle intent passed in by StartService () or Bindservice (). If the service is started, the service is still active when the end of the service's life cycle is the end of the active time (from Onstartcommand (). If the service is bound, Onunbind () returns, the service's life is over.

Note: If a started service is stopped by calling Stopself () or StopService (), there is no callback associated with it (no OnStop () callback).
Therefore, unless the service is bound to a client, if the service is stopped, the system destroys it, and OnDestroy () is the only callback that the service receives.


Android-service components

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.