Detailed service usage in Android

Source: Internet
Author: User

Service is used for long-term processing of tasks in the background without the need to be visible to the user.
The service has 2 basic boot methods:
StartService (): Use this method to perform a single task without having to return the result to the caller
Bindservice (): Contrary to the above.


Here are some important notes about the service that are worth knowing more about:


Inherit service, realize own service;
In manifest, the service is declared in the main thread and does not create its own child threads.
Here are some of the overriding methods:


OnCreate (); Called only once when the service is created.


Onstartcommand (); It corresponds to StartService (), which is called when the service is started. If you rewrite the method, you have the responsibility to do it yourself.
When the task is finished, call Stopself () or StopService () to stop the service. If you are a bundled service, you do not need to re-approach the method.


Onbind (), which corresponds to Bindservice (), communicates with the service by returning to the IBinder. If you are not bound to it, return null directly


OnDestroy (); Called when the service is no longer being used when it needs to be destroyed, you should be here to stop the thread, unregister the listener, broadcast.


If a component, such as activity, uses StartService () to start the service, it will trigger Onstartcommand () and the service will run until the end of the task, and the service needs to stop.
Manual control: Call StopService () in the component that started the service or call Stopself () in the service class


If a component uses Bindservice () to start the service, the service runs until the component does not constrain it.


In the case of low system memory, the system will force the service to resume to run the activity, but the services under these circumstances are not easy to be stopped by the system: the service is bound to activity or
The service is located at the front desk. But if the service is finally stopped, we need to re-enable the service.


the creation and use of service,

You can also use Intentservice, which is a service subclass, which does not require your own thread to handle background tasks and can be performed directly in Onhandleintent ().

<span style= "FONT-SIZE:14PX;" >1.<manifest ... > <application ... > <service android:name= ". Exampleservice "android:exported=" false "/> ... </application></manifest>public class Hel Lointentservice extends Intentservice {A constructor is required, and must call the Super Intentservice (String) con  Structor 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 fil      E.//For our sample, we just sleep for 5 seconds.      try {thread.sleep (5000);          } catch (Interruptedexception e) {//Restore interrupt status. Thread.currentthreaD (). interrupt (); }}}</span>
<span style= "FONT-SIZE:14PX;" ></span>

With Intentservice, the service is automatically closed after the task is finished.

2. Use StartService () to start the service, which is typically used in situations where interaction is not required.acceptance of Intent in onstartcommand ();
Intent Intent = new Intent (this, helloservice.class);
StartService (Intent);


If your service is not bound, then the intent in StartService (intent) is the only way to interact with the service, and the service is broadcast to publish callbacks out. If the service is started multiple times, Onstartcommand () will be called multiple times.


Onstartcommand () must return an integer value describing how the system will continue to service when the system kills
Start_not_sticky, after killing, no longer rebuilt
Start_sticky, after killing, automatically restarts, and then receives the Intent=null
Start_redeliver_intent, after killing, automatically restarts, and then receives the INTENT is not empty; like file download

3. Use Bindservice () to start up; This approach is more complex, but more flexible. You can use this approach when you need to interact with the service;
You must override the Onbind () method to return IBinder to communicate with other components. Get the IBinder object in another component
There is a sense of client-server that can have multiple clients communicating with the server


Client components, you must create a serviceconnection to listen to the connection to the service;
There can be multiple clients connecting to the service, but the service's onbind is executed only once, so the same IBinder object is distributed to other clients
The service is destroyed only after the service has been unbound by multiple clients.


One of the most important places to use this service is to define IBinder;
There are 3 ways of doing this:
A. Direct inheritance of binders, which is also a common way for general apps, is for your service to be in the same process as your app. Your service is just for
Handles background tasks.


B. Using Messenger, which is suitable for cross-process communication and is thread-safe and non-concurrent, only one request can be accepted at the same time, and you use the 2 classes of Messenger and handler for service and client interaction.

The server establishes the Messenger object by onbind the server Messenger object to the client by placing it in Ibind, so that the client can get the server Messenger object and use the Server Messenger object to send the message to the service end.

After the client connection on the server side, you can establish a client Messenger object, the client Messenger object in the form of a message to the server, the service side to get the client Messenger object can send messages to the client.

This is thread-safe. Because they are all in the same queue, thread on the same line. It is built on Aidl itself.



C. Use aidl for situations that require cross-process, non-thread-safe, ability to handle multiple requests at the same time.
Its use is to create a. aidl file, which defines the interface, and then the Android SDK tool uses it to generate an abstract class that implements various interface methods in the abstract class.
Note: For most applications, we should not use Aidl to bindservice. Because it makes the results more complicated.


First we look at the first way; directly inherit binder,For example, a scene where an app is used for music playback, it's associated with an activity. Activity enables the service to play music in the background.


Service side:

<span style= "FONT-SIZE:14PX;" >public class LocalService extends Service {    //Binder given to clients    private final IBinder mbinder = new Loc Albinder ();    Random number generator    private final random mgenerator = new Random ();     Class used for the client Binder.  Because We know this service     is always//runs in the same process as its clients, we don ' t need to deal with IPC.    public class Localbinder extends binders {        LocalService getService () {            //Return This instance of LocalService so C Lients can call public methods            return localservice.this;        }    }    @Override public    IBinder onbind (Intent Intent) {        return mbinder;    }    Method for clients public     int GetRandomNumber () {      return Mgenerator.nextint (+)}    } </span>

Client:

<span style= "FONT-SIZE:14PX;"    >public class Bindingactivity extends Activity {LocalService mservice;    Boolean mbound = false;        @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);    Setcontentview (R.layout.main);        } @Override protected void OnStart () {Super.onstart ();        Bind to LocalService Intent Intent = new Intent (this, localservice.class);    Bindservice (Intent, mconnection, context.bind_auto_create);        } @Override protected void OnStop () {super.onstop ();            Unbind from the service if (mbound) {unbindservice (mconnection);        Mbound = false; }}//** called when a button was clicked (the button in the layout of the file attaches to//* This method with the  Droid:onclick attribute) public void OnButtonClick (View v) {if (Mbound) {//Call a method from the            LocalService. However, if This call were something the might hang and then the request should//occur in a separate the thread to avoid slow            ing down the activity performance.            int num = Mservice.getrandomnumber ();        Toast.maketext (This, "number:" + num, Toast.length_short). Show (); }}//defines callbacks for service binding, passed to Bindservice () private serviceconnection mconnection = new S Erviceconnection () {@Override public void onserviceconnected (ComponentName className, Ibinde R Service) {//We ' ve bound to LocalService, cast the IBinder and get LocalService instance Localbin            Der Binder = (localbinder) service;            Mservice = Binder.getservice ();        Mbound = true;        } @Override public void onservicedisconnected (ComponentName arg0) {mbound = false; }    };} </span>


Next we look at the second way; using Messenger,

If you only need to interact with the service when the Activity is visible, you should bind during OnStart () and Unbind during OnStop ().

If you want Activity to still receive a response while the background is stopped running, you can bind during onCreate () and Unbind during OnDestroy (). Note that this means that your Activity needs to use the service throughout its run, even during the background run, so if the service is in another process, the likelihood of the system terminating the process increases when you increase the weight of the process.

The following is a complete example: the client and the server use Messenger to communicate.

Service side: Server_service

<span style= "FONT-SIZE:14PX;" >package Com.example.administrator.service_messenger;import Android.app.service;import android.content.Intent; Import Android.content.serviceconnection;import Android.os.handler;import Android.os.ibinder;import Android.os.message;import android.os.messenger;import Android.os.remoteexception;import android.widget.Toast;/** * Declare the service as another new process in the manifest manifest file.    */public class Server_service extends Service {private Messenger clientmessenger; /** * Server Handler */class Serverhandler extends Handler {@Override public void Handlemessage (Me Ssage msg) {switch (msg.what) {case Client.MSG_FROM_CLIENT:String Fromclie                    NT = Msg.getdata (). getString ("Msgfromclient");                    Receive information from the client Toast.maketext (Getapplicationcontext (), Fromclient, Toast.length_short). Show (); Reply to client Message msgfromserver = Message.obtain (null, ClieNt.                    Msg_from_server);                    MSGFROMSERVER.ARG1 = 200;                    try {clientmessenger.send (msgfromserver);                    } catch (RemoteException e) {e.printstacktrace ();                } break;                    Case Client.msg_from_client_messe://Get client Messenger Object Clientmessenger = Msg.replyto;            Break     }}}/** * service-side Messenger, using the server-side handler to do the parameter construction.    */FINAL Messenger Servermessenger = new Messenger (new Serverhandler ()); /** * Here we use the IBinder of the service-side Messenger object Servermessenger to return it to the client's * serviceconntected */@Override public IBinder        Onbind (Intent Intent) {Toast.maketext (Getapplicationcontext (), "Client Binding server succeeded", Toast.length_short). Show ();    return Servermessenger.getbinder ();        } @Override public void Unbindservice (Serviceconnection conn) {Super.unbindservice (conn); Toast.maketext (GetappLicationcontext (), "Client canceled service binding", Toast.length_short). Show (); }}</span>
under Manifest configuration:

<span style= "FONT-SIZE:14PX;" ><service android:name= ". Server_service "            android:process=": v1 "/></span>

Clients: Client
<span style= "FONT-SIZE:14PX;" >package Com.example.administrator.service_messenger;import Android.content.componentname;import Android.content.context;import Android.content.intent;import Android.content.serviceconnection;import Android.os.bundle;import Android.os.handler;import Android.os.ibinder;import Android.os.message;import Android.os.messenger;import Android.os.remoteexception;import Android.support.v7.app.appcompatactivity;import Android.view.view;import Android.widget.toast;import Java.io.unsupportedencodingexception;import    Java.util.calendar;public class Client extends Appcompatactivity {public static final int msg_from_client = 1;    public static final int msg_from_client_messe = 2;    public static final int msg_from_server = 3;    The Messenger object Messenger Servermessenger = null is received on the client side of the server;    Whether the token is already connected to the service-side Boolean mbound;        @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (r.layout.Activity_client); Bind service Findviewbyid (r.id.bt_bind). Setonclicklistener (New View.onclicklistener () {@Override P            ublic void OnClick (View v) {bindservice ();        }        });            Send messages to the server Findviewbyid (r.id.bt_send) via messenger from the service side. Setonclicklistener (New View.onclicklistener () {@Override                public void OnClick (View v) {try {sendinfotoserver ();                } catch (Unsupportedencodingexception e) {e.printstacktrace ();        }            }        });            Manual unbind Service Findviewbyid (r.id.bt_unbind). Setonclicklistener (New View.onclicklistener () {@Override            public void OnClick (View v) {unbindservice ();    }        });        } @Override protected void OnDestroy () {Super.ondestroy ();    When the activity is destroyed, you can choose to unbind the service Unbindservice (); }//Client Handler private Handler ClienthanDler = new Handler () {@Override public void Handlemessage (Message msg) {switch (msg.what) { Case MSG_FROM_SERVER:Toast.makeText (Getapplicationcontext (), "SERVER Received:" +msg.arg1                    + "", Toast.length_short). Show ();            Break    }        }    };     /** * Client Messenger, using the customer's handler to do the parameter construction.    */FINAL Messenger Clientmessenger = new Messenger (ClientHandler); Private Serviceconnection mconnection = new Serviceconnection () {public void onserviceconnected (ComponentName clas SName, IBinder Service) {//When we connect to the server, the method is called.            In the method the callback is given to us IBinder object,//The ibinder that the server returns to the client is the same after Bindservice binds the service.            So here we can use IBinder to build the Messenger object on the service side.            After having the Messenger object on the service side, you can send the message to the Web server.            Build the service-side Messenger Object Servermessenger = new Messenger (service);            Mbound = true; And the client Messenger to the server, so that the server can also send messages to the client message msg = Message.obtain (null, MSG_FROM_client_messe);            Msg.replyto = Clientmessenger;            try {servermessenger.send (msg);            } catch (RemoteException e) {e.printstacktrace (); }} public void onservicedisconnected (ComponentName className) {//Call server when connecting to a service-side exception            Messenger = null;        Mbound = false;    }    };        private void Sendinfotoserver () throws Unsupportedencodingexception {if (!mbound) return;        Message msg = Message.obtain (null, msg_from_client, 0, 0);        String STRMSG = "Server Received:" + calendar.getinstance (). GetTime ();        Bundle data = new bundle ();        Data.putstring ("Msgfromclient", STRMSG);        Msg.setdata (data);        try {servermessenger.send (msg);        } catch (RemoteException e) {e.printstacktrace ();        }} @Override protected void OnStart () {Super.onstart (); When the interface is visible, you can choose to bind the service} @Override protected void OnStop () {super.onstop (); When the interface is not visible, you can choose to unbind the service} private void Bindservice () {Bindservice (new Intent (this, server_service.class), Mconn    Ection, context.bind_auto_create);            } private void Unbindservice () {if (mbound) {unbindservice (mconnection);        Mbound = false; }}}</span>


Finally, let's look at the third way of using aidl:







Detailed service usage in Android

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.