Services
Services: Can be run in the background for a long time without a UI interface.
Started:
Services can be started by calling StartService through other components, running in the background, even if the component that started it has been destroyed. Typically this service performs a specific operation and does not return a value, such as downloading or uploading a file over the network, and once the operation is finished, the service needs to stop itself.
Bound:
The service invokes the Bindservice binding through other components, providing an interface to the CS architecture that allows other components to interact with the service, send messages, get return values, and even communicate across processes. The bound service survives with the components that bind it, and multiple components can bind to a service that is destroyed when all the components that bind it are unbound.
Caution:service runs on the main thread of the host process, which means that the service does not create its own thread, nor does it run in another process (unless you specify). This means that if the service performs some task of high CPU load or blocking interface operation, you need to create a new thread to run it to reduce the risk of ANR.
(using service or thread?) If you just need to perform additional tasks outside the main thread while interacting with the user, you need to create a new thread instead of a service. For example, when activity plays music at the foreground, you need to create threads in OnCreate, thread in OnStart, stop threads in OnStop, or use Asynctask or handlethread instead of thread classes. )
Basis
Create a subclass of the service, overwrite the key callback functions in the service life cycle, and, if necessary, provide a mechanism for binding the service. The most important callback functions are as follows:
Onstartcommand
The system executes when another component calls StartService to start the service, and then the service is executed in the background. If you implement this method, you are responsible for stopping the service by stopself or StopService when the service completes its work. (If you only provide a bound service, you can not implement this method)
Onbind
The system executes when other components call Bindservice to bind the service, and in the implementation of this method you need to return an Ibider interface for clients to interact with the service. If you do not need to bind, you can return null directly
OnCreate
The service is executed the first time it is created, and before Onstartcommand and Onbind, it is used to perform a once-in-a-kind data initialization.
OnDestroy
Service is executed when it is destroyed, used to clean up resources, similar threads, registered listeners, receiver, etc.
The system forces the service to stop at low memory. If the service is bound to an activity with a user focus, it will rarely be destroyed, and if it is defined as running in the foreground, it will never be destroyed.
Define Service in Manifest
< manifest ... > ... < application ... > < service android:name = ". Exampleservice " /> ... </ application > </ manifest >
Android:name is the only required attribute, and the others are optional. Once your app is published, Android:name never change.
For security, use an explicit intent to start or bind the service instead of defining filiters. If you do allow multiple services to respond, be sure to specify enrollment in intent by setpackage to reduce the probability that the target service will match unexpectedly.
Set android:exported to False to prevent other apps from starting the service.
Create service
Service
The base class for all services, if you extend this class, then you may need to create a new thread, because this service room is executed in the main thread of the app, which may reduce the fluidity of the activity
Intentservice
A subclass of the Service that processes all requests through a worker thread, one at a time. If your service does not need to process multiple requests at the same time, Intentservice is the best choice.
Extended Intentservice
Intentservice is the best recommendation because most services do not need to process multiple requests at the same time (actually a multi-threaded scenario)
The Intentservice workflow is as follows:
- Create a default new worker thread to perform all intents that are distributed to Onstartcommand
- Create a work queue to pass intent in turn to perform onhandleintent implementation, so you don't need to consider multithreaded scenarios
- After all requests are executed, automatic destruction, you do not need to execute stopself
- Provides the default Onbind implementation: returns null directly
- Provides onstartcommand default implementation: Sends intent to worker threads to perform onhandleintent implementations
In fact, all you need to do is implement Onhandleintent, as in the following example:
Public classHellointentserviceextendsIntentservice {/*** A constructor is required, and must call the Super Intentservice (String) * constructor with A name for the work ER thread. */ PublicHellointentservice () {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. */@Overrideprotected voidonhandleintent (Intent Intent) {//normally we would do some work here, like download a file. //for our sample, we just sleep for 5 seconds. LongEndTime = System.currenttimemillis () + 5*1000; while(System.currenttimemillis () <endTime) { synchronized( This) { Try{Wait (endTime-System.currenttimemillis ()); } Catch(Exception e) {}}} }}
If you need to overwrite other callbacks, such as OnCreate, Onstartcommand, OnDestroy, make sure that you invoke the implementation of the parent class so that the Intentservice can handle the worker thread's life cycle. Onhandleintent and Onbind are exceptions.
Extended Service
If the service needs to support multithreading (rather than one by one processing through a work queue), then you need to extend the service to handle each intent.
As a comparison, the following code is the same as the code above.
Public classHelloServiceextendsService {PrivateLooper Mservicelooper; PrivateServicehandler Mservicehandler; //Handler that receives messages from the thread Private Final classServicehandlerextendsHandler { PublicServicehandler (Looper Looper) {Super(Looper); } @Override Public voidhandlemessage (Message msg) {//normally we would do some work here, like download a file. //for our sample, we just sleep for 5 seconds. LongEndTime = 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, we don ' t Stop//The service in the middle of handling another jobstopself (MSG.ARG1); }} @Override Public voidonCreate () {//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-cpu-intensive work won't disrupt our UI.Handlerthread thread =NewHandlerthread ("Servicestartarguments", Process.thread_priority_background); Thread.Start (); //Get The Handlerthread ' s Looper and use it for our HandlerMservicelooper =Thread.getlooper (); Mservicehandler=NewServicehandler (Mservicelooper); } @Override Public intOnstartcommand (Intent Intent,intFlagsintStartid) {Toast.maketext ( This, "Service Starting", Toast.length_short). Show (); //for each start request, send a message to start a job and deliver the//start ID so we know which request we ' re stopping when we finish the jobMessage msg =Mservicehandler.obtainmessage (); Msg.arg1=Startid; Mservicehandler.sendmessage (msg); //If We get killed, after returning from here, restart returnStart_sticky; } @Override Publicibinder onbind (Intent Intent) {//We don ' t provide binding, so return null return NULL; } @Override Public voidOnDestroy () {Toast.maketext ( This, "Service Done", Toast.length_short). Show (); }}
This is just a simulated intentservice processing, and if necessary, you can create a thread for each request.
The Onstartcommand must return an integral type that describes how the system handles the service when it is destroyed by an exception.
Start_not_sticky
If the service is destroyed by an exception after executing Onstartcommand, there is no need to recreate the service unless there is an unhandled intents. Avoid services being unnecessarily started, and your app can easily restart unfinished work and choose this.
Start_sticky
If the service finishes executing Onstartcommand and is destroyed by an exception, re-creates the service and executes Onstartcommand, but does not use the last intent sent to the service, but executes onstartcommand through a null intent. Unless there is an unhandled intents. This situation is more appropriate for not executing commands, running in the background, or waiting for the media to play the task.
Start_redeliver_intent
If the service finishes executing Onstartcommand and is destroyed by an exception, re-creates the service, calls Onstartcommand with the last intent sent to the service, and distributes the other unhandled intents in turn. This scenario is suitable for performing tasks that require an understanding of the recovery scenario, such as downloading files.
Start the service
Startservice–> Onstartcommand
New Intent (This, HelloService. Class); StartService (intent);
The StartService method returns immediately.
If the service is not bound and can only be started through StartService, and the return value needs to be sent, the services can be started by creating a pendingintent with deferred broadcasts (with Getbroadcast), and the service can distribute the results using the broadcasts inside.
Stop Service
If the service processes multiple requests synchronously, it cannot be destroyed directly after processing a request, and it is possible that other requests have just been sent or are still in process. To avoid this, you can use stopself (int) to ensure that the closed service is just processing the request, not the other service being processed, and the integer parameter uniquely identifies the service instance.
Create a binding service
See the next section
Send notifications to User
Once the service is running, users can be alerted through toast notifications and status Bar notifications.
Running the service in the foreground
The service running in the foreground must provide a status bar notification to render the running state, and notification will not disappear unless the service is stopped or removed.
For example: Play music, there is a notification in the status bar to tell the user the song currently playing, provide users access to the music player entrance
The service needs to be run in the foreground, call Startforground, the first parameter is the unique identifier of the notification (cannot be 0), the first parameter is notification, for example:
New Notification (R.drawable.icon, GetText (r.string.ticker_text), new Intent (This, Exampleactivity. class = 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);
Stop running in the foreground, you can call Stopforeground.
Implementing Life cycle Callbacks
Public classExampleserviceextendsService {intMstartmode;//indicates how to behave if the service is killedIBinder Mbinder;//interface for clients that bind BooleanMallowrebind;//Indicates whether Onrebind should be used@Override Public voidonCreate () {//The service is being created} @Override Public intOnstartcommand (Intent Intent,intFlagsintStartid) { //The service is starting, due to a call to StartService () returnMstartmode; } @Override Publicibinder onbind (Intent Intent) {//A Client is binding to the service with Bindservice () returnMbinder; } @Override Public BooleanOnunbind (Intent Intent) {//All clients has unbound with unbindservice () returnMallowrebind; } @Override Public voidOnrebind (Intent Intent) {//A Client is binding to the service with Bindservice (),//After Onunbind () have already been called} @Override Public voidOnDestroy () {//The service is no longer used and is being destroyed }}
Note: You do not need to perform the implementation of the parent class.
Full life cycle:oncreate-> OnDestroy
Life cycle of activities:onstartcommand/onbind-> Ondestroy/onunbind