Basic knowledge of Android 05: Service 01 of four components

Source: Internet
Author: User

This topic describes services. There are two articles:

Basic knowledge of Android 05: Service 01 of four components

Android basic knowledge 05: four major components-service 02: Remote Call

Android basic knowledge 05: four major components-service 03: Implementation Mechanism

This document is sourced from the Internet. For more information, see the android service analysis on the Internet.

Instance program address: http://download.csdn.net/detail/xianming01/4131098

Http://download.csdn.net/detail/xianming01/4131146

1. What is service?

Service. The name is similar to the "service" that we normally understand. It runs in the background and can interact with each other. It is similar to the activity level, but it cannot be run by itself. It needs to be called through an activity or other context object, context. startservice () and context. bindservice ().
The two methods for starting a service are different. It should be noted that if you do some time-consuming things in oncreate or onstart of the Service, it is best to start a thread in the service to complete it, because the service is running in the main thread, it will affect your UI operations or block other things in the main thread.
When do I need a service? For example, when the user starts other activities during multimedia playback, the program will continue playing in the background, for example, detecting file changes on the SD card, or recording changes to your location in the background, in short, services are always hidden behind the scenes.

The service runs in the background for a period of time and does not interact with the application components. Each service must be declared in manifest through <service>. It can be started through contect. startservice and contect. bindserverice.
Like other application components, the service runs in the main process. This means that if the service requires a lot of time-consuming or congested operations, it needs to be implemented in its subthread.
The two service modes (startservice ()/bindservice () are not completely separated ):
1) the local service is used inside the application.
It can be started and run until someone stops it or it stops it. In this way, it starts by calling context. startservice () and ends by calling context. stopservice. It can call service. stopself () or service. stopselfresult () to stop itself. No matter how many times the startservice () method is called, you only need to call stopservice () once to stop the service.
It is used to implement some time-consuming tasks of the application itself, such as querying the upgrade information. It does not occupy the application, such as the thread to which the activity belongs, but is executed in the single-thread background, so that the user experience is better.
2) remote service is used between applications in the Android system.
It can perform program operations through APIS defined and exposed by itself. The client establishes a connection to the service object and calls the service through that connection. Connection to call the context. bindservice () method to establish, to call context. unbindservice () to close. Multiple clients can be bound to the same service. If the service is not loaded yet, bindservice () loads it first.
It can be reused by other applications, such as the weather forecast service. Other applications do not need to write such services and can call existing services.

2. Local Services

2.1 startservice Method

Service Startup Method 1:
Start: context. startservice (new intent (context, XXX. Class ));
Stop: context. stopservice ();
I drew a Service Startup flowchart. I believe you will understand it at a glance. Activity starts the service through intent. if the service is not running, Android first calls oncreate () and then calls onstart (). if the service is already running, only onstart () is called (), therefore, the onstart method of a service may be called multiple times. When stopservice is called, The ondestroy () method of the service is triggered. Image click to enlarge ~

Let's first introduce the example of a local service.

2.1.1 Interface

You can play music, pause, stop, and so on. At the same time, click Finish to close the application (but the service is not closed, and the music can be played again), click exit to launch the application, and close the service.

2.1.2 playing music

/*** Classname: mymediacontroller * function: A control class of mediaplayer, control the player's pause and other actions * Reason ** @ author Leon * @ version * @ since ver 1.1 * @ date 2011-5-16 */Public Enum mymediacontroller implements serializable {play {@ overridepublic void execute () {If (mediaplayer! = NULL &&! Mediaplayer. isplaying () mediaplayer. start (); // todo auto-generated method stub }}, pause {@ overridepublic void execute () {// todo auto-generated method stubif (mediaplayer! = NULL & mediaplayer. isplaying () {mediaplayer. pause () ;}}, stop {@ overridepublic void execute () {// todo auto-generated method stubif (mediaplayer! = NULL) {mediaplayer. stop (); try {// after stopping, if you want to start again, you need to prepare mediaplayer. prepare (); // play mediaplayer from scratch. seekto (0);} catch (exception e) {// todo auto-generated catch blocke. printstacktrace () ;}}}; public static mediaplayer; public abstract void execute ();}

2.1.3 Service

 /** * ClassName:MusicService * Function: TODO ADD FUNCTION * Reason: TODO ADD REASON * * @author   Leon * @version * @since    Ver 1.1 * @Date 2011-5-15 */public class MusicService extends Service{ private  String  TAG = MusicService.class.getSimpleName();private  MediaPlayer myMediaPlayer ;public   static final  String INTENT_KEY= "action" ;@Overridepublic IBinder onBind(Intent arg0) {  // TODO Auto-generated method stubreturn null; } @Overridepublic void onCreate() { // TODO Auto-generated method stubLog.v(TAG , TAG+ " onCreate()");super.onCreate();if(myMediaPlayer==null){myMediaPlayer=MediaPlayer.create(this, R.raw.test) ;myMediaPlayer.setLooping(false);}} @Overridepublic void onStart(Intent intent, int startId) {// TODO Auto-generated method stubLog.v(TAG , TAG + " onStart()");super.onStart(intent, startId);if(intent!=null){MyMediaController mediaControl =(MyMediaController)intent.getSerializableExtra(MusicService.INTENT_KEY);mediaControl.mediaPlayer=myMediaPlayer;mediaControl.execute();}} @Overridepublic void onDestroy() { // TODO Auto-generated method stubsuper.onDestroy();Log.v(TAG , " onDestroy");if(myMediaPlayer!=null){myMediaPlayer.stop();myMediaPlayer.release();} } }

2.1.4 Interface

public class ServiceTestServerActivity extends Activity implements OnClickListener{    /** Called when the activity is first created. */private static final String TAG = ServiceTestServerActivity.class.getSimpleName();private TextView m_TextView_text;private Button btnPlay;private Button btnPause;private Button btnStop;private Button btnFinish;private Button btnExit;Intent intent;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                m_TextView_text= (TextView)findViewById(R.id.text);                btnPlay= (Button)findViewById(R.id.play);        btnPause= (Button)findViewById(R.id.pause);        btnStop= (Button)findViewById(R.id.stop);        btnFinish= (Button)findViewById(R.id.finish);        btnExit= (Button)findViewById(R.id.exit);                btnPlay.setOnClickListener(this);        btnPause.setOnClickListener(this);        btnStop.setOnClickListener(this);        btnFinish.setOnClickListener(this);        btnExit.setOnClickListener(this);                intent=new Intent("xuxm.demo.service01.MusicService");    }        private void playAction(MyMediaController playType) {     Bundle bundle = new Bundle();bundle.putSerializable(MusicService.INTENT_KEY, playType);intent.putExtras(bundle);ServiceTestServerActivity.this.startService(intent);}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch(v.getId()){case R.id.play:playAction(MyMediaController.play);m_TextView_text.setText(R.string.play);Log.d(TAG, "play.......");break;case R.id.pause:playAction(MyMediaController.pause);m_TextView_text.setText(R.string.pause);Log.d(TAG, "pause.......");break;case R.id.stop:playAction(MyMediaController.stop);m_TextView_text.setText(R.string.stop);Log.d(TAG, "stop.......");break;case R.id.finish:Log.d(TAG, "close.......");this.finish();break;case R.id.exit:Log.d(TAG, "exit.......");stopService(intent);this.finish();break;default:}}}

The program is quite simple, so I will not analyze it.

During the first startservice operation, you can find that oncreate and onstart will be called. Before there is no stopservice, only onstart will be called no matter how many times startservice is clicked. The stopservice calls ondestroy. Click stopservice again and you will find that it does not enter the service lifecycle, that is, it will not call oncreate, onstart and ondestroy.
Onbind is not called in startservice/stopservice.

2.1 bind Service Mode
The second is to start the service by binding it. First look at the flowchart and click to zoom in.

Here we use this. bindservice (intent, myserviceconnection, context. bind_auto_create); to start the service. After the service is created and bound at the same time, the serviceconnection () defined by us will be called back to return the ibinder interface, so that we can call the methods in the service. At this time, the activity is bound to the service, and the activity exits after exiting the service.

<service android:name=".MusicService02" >            <intent-filter >                <action android:name="xuxm.demo.service02.MusicService" />            </intent-filter>            </service>

The main code is as follows:

Musicservice02

Public class musicservice02 extends Service {private string tag = musicservice02.class. getsimplename (); Private mediaplayer mymediaplayer; public static final string intent_key = "action"; @ overridepublic ibinder onbind (intent arg0) {// todo auto-generated method stublog. V (TAG, tag + "onbind"); Return mbinder;} localbinder mbinder = new localbinder (); public class localbinder extends binder {musicservice 02 getservice () {return musicservice02.this ;}@ overridepublic void oncreate () {// todo auto-generated method stublog. V (TAG, tag + "oncreate ()"); super. oncreate (); If (mymediaplayer = NULL) {mymediaplayer = mediaplayer. create (this, R. raw. test); mymediaplayer. setlooping (false) ;}@overridepublic void onstart (intent, int startid) {// todo auto-generated method stublog. V (TAG, tag + "onstart ()" ); Super. onstart (intent, startid) ;}@ overridepublic Boolean onunbind (intent) {// todo auto-generated method stublog. V (TAG, tag + "onunbind, success? "+ Super. onunbind (intent); Return true; // return false ;}@ overridepublic void onrebind (intent) {// todo auto-generated method stublog. V (TAG, tag + "onrebind () ------------------------------------->"); super. onrebind (intent) ;}@ overridepublic void ondestroy () {// todo auto-generated method stubsuper. ondestroy (); log. V (TAG, "ondestroy"); If (mymediaplayer! = NULL) {mymediaplayer. stop (); mymediaplayer. release () ;}} public mediaplayer getmymediaplayer () {return mymediaplayer;} public void setmymediaplayer (mediaplayer mymediaplayer) {This. mymediaplayer = mymediaplayer ;}}

Servicetestserveractivity

Public class servicetestserveractivity extends activity implements onclicklistener {/** called when the activity is first created. */Private Static final string tag = servicetestserveractivity. class. getsimplename (); Private textview m_textview_text; private button btnplay; private button btnpause; private button btnstop; private button btnunbind; private button btnfinish; private button btnexit; private musicservice02 bindmusicservice; @ override public void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (R. layout. main); m_textview_text = (textview) findviewbyid (R. id. text); btnplay = (button) findviewbyid (R. id. play); btnpause = (button) findviewbyid (R. id. pause); btnstop = (button) findviewbyid (R. id. stop); btnfinish = (button) findviewbyid (R. id. finish); btnexit = (button) findviewbyid (R. id. exit); btnplay. setonclicklistener (this); btnpause. setonclicklistener (this); btnstop. setonclicklistener (this); btnfinish. setonclicklistener (this); btnexit. setonclicklistener (this); connection ();} private void connection () {log. V (TAG, tag + "connection"); intent = new intent ("xuxm. demo. service02.musicservice "); // This. startservice (intent); this. bindservice (intent, myserviceconnection, context. bind_auto_create) ;}@ overridepublic void onclick (view v) {// todo auto-generated method stubswitch (v. GETID () {case R. id. play: mymediacontroller.play.exe cute (); m_textview_text.settext (R. string. play); log. D (TAG, "play ....... "); break; case R. id. pause: mymediacontroller.pause.exe cute (); m_textview_text.settext (R. string. pause); log. D (TAG, "pause ....... "); break; case R. id. stop: mymediacontroller.stop.exe cute (); m_textview_text.settext (R. string. stop); log. D (TAG, "stop ....... "); break; case R. id. finish: log. D (TAG, "close ....... "); this. finish (); break; case R. id. exit: log. D (TAG, "exit ....... "); this. finish (); this. stopservice (new intent ("xuxm. demo. service02.musicservice "); break; default: }}// after bindservice is called, the service calls onbind () and calls back this function private serviceconnection myserviceconnection = new serviceconnection () {@ overridepublic void onserviceconnected (componentname, ibinder binder) {// This is called when the connection with the service has been // established, giving us the service object we can use to // interact with the service. because we have bound to a explicit // service that we know is running in our own process, we can // cast its ibinder to a concrete class and directly access it. log. V (TAG, tag + "onserviceconnected"); // todo auto-generated method stubbindmusicservice = (localbinder) binder ). getservice (); // set the mediaplayermymediacontroller initialized by the Service for the controller. mediaplayer = bindmusicservice. getmymediaplayer () ;}@ overridepublic void onservicedisconnected (componentname name) {// This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. // because it is running in our same process, we shoshould never // see this happen. // todo auto-generated method stubbindmusicservice = NULL; log. V (TAG ,".............. onservicedisconnected ") ;}}; // when the activity is finished, it must be unbound. Otherwise, the overflow @ overridepublic void finish () {// todo auto-generated method stubsuper will occur. finish (); this. unbindservice (myserviceconnection );}}

During running, we found that the call order is as follows:
Bindservice:
1. musicservice02: oncreate
2. musicservice02: onbind
3. Activity: onserviceconnected
Unbindservice: Only ondestroy is called.
It can be seen that onstart is not called, and the reason why onservicedisconnected is not called is described in the comments of the code above.

At this time, the service is stopped when the activity is stopped.

2.2 bind service problems

In the previous analysis, we can see that activity and service, context. startservice correspond to the onstart () method in service, and context. onbindservice corresponds to the onbind () method in service. When we want to bind a service and stop the activity, the service will not stop. We can first startservice and then bindservice (). The flowchart is as follows:

At this time, you need to pay attention to a problem. When the activity exits, sercvice will not stop. Now we can re-bind the activity. At this time, the service will call the onrebind () method, however, the prerequisite for calling the onrebind () method is that the previous onunbind () method is successfully executed, but super is used. onunbind (intent) is not successful. At this time, we need to manually make it return true, and rebind () will be executed when it is bound again. Otherwise, if the specified onunbind () that is not displayed at exit is successful (false), restart this activity to bind the service, the onbind () of the service () method and onrebind will not be executed, but the serviceconnection method will definitely call back. This indicates that the onbind () method in service is different from the onstart () method and cannot be called repeatedly.

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.