android服务之一 Service

Service是Android系统中四大组件之一(Activity、Service、BroadcastReceiver、ContentProvider),它和Activity的级别差不多,区别在于,Activity有界面显示,而Service是在后台运行,它是不可见的,可以和其他组件进行交互。


Service服务的启动有两种方式


1:本地服务context.startService()
context.startService() ->onCreate()- >onStart()->Service running--调用context.stopService() ->onDestroy()

如果Service还没有运行,则android先调用onCreate(),然后调用onStart();
如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。
如果stopService的时候会直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行,该Service的调用者再启动起来后可以通过stopService关闭Service。
所以调用startService的生命周期为:onCreate --> onStart (可多次调用) --> onDestroy

2:远程服务context.bindService()
context.bindService()->onCreate()->onBind()->Service running--调用>onUnbind() -> onDestroy()

onBind()将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service的实例、运行状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。 
所以调用bindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。
在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。

两者区别如图所示:

                                   

简单音乐播放代码如下:

配置AndroidManifest.xml:

<!-- 启动服务 -->
        <service android:name="com.example.service.PlyMusicService" />

.xml文件里只4个button,就省略了吧

 1 package com.example.practice5_service;
 2 
 3 import com.example.service.PlyMusicService;
 4 
 5 import android.app.Activity;
 6 import android.content.ComponentName;
 7 import android.content.Context;
 8 import android.content.Intent;
 9 import android.content.ServiceConnection;
10 import android.os.Bundle;
11 import android.os.IBinder;
12 import android.view.Menu;
13 import android.view.MenuItem;
14 import android.view.View;
15 import android.view.View.OnClickListener;
16 import android.widget.Button;
17 
18 public class MainActivity extends Activity implements OnClickListener,ServiceConnection{
19     Button startService,stopService,bindService,unbindService;
20     @Override
21     protected void onCreate(Bundle savedInstanceState) {
22         super.onCreate(savedInstanceState);
23         setContentView(R.layout.activity_main);
24         initView();
25     }
26     public void initView(){
27         startService=(Button) findViewById(R.id.startService);        
28         stopService=(Button) findViewById(R.id.stopService);
29         bindService=(Button) findViewById(R.id.bindService);
30         unbindService=(Button) findViewById(R.id.unbindService);
31         startService.setOnClickListener(this);
32         stopService.setOnClickListener(this);
33         bindService.setOnClickListener(this);
34         unbindService.setOnClickListener(this);
35     }
36     @Override
37     public void onClick(View v) {
38         // TODO Auto-generated method stub
39         switch (v.getId()) {
40         case R.id.startService:
41             /**
42              * 此处启动走service里的onCreate和onStartCommand,
43              * 终止走service里的onDestroy
44              * 即使退出activity,service仍然继续执行,除非执行stopService
45              */            
46             Intent startIntent=new Intent(this,PlyMusicService.class);
47             Bundle bundle=new Bundle();//传值
48             bundle.putString("name", "hhg");
49             startIntent.putExtra("info", bundle);
50             startService(startIntent);
51             break;
52         case R.id.stopService:
53             stopService(new Intent(this,PlyMusicService.class));
54             break;
55         case R.id.bindService:
56             /**
57              * 绑定服务后,service和activity一起停止
58              */
59             super.bindService(new Intent(this,PlyMusicService.class), this,
60                     Context.BIND_AUTO_CREATE);//绑定服务(退出activity时结束服务)
61             break;
62         case R.id.unbindService:
63             if(binder!=null){
64                 super.unbindService(this);//取消绑定
65             }
66             break;
67         default:
68             break;
69         }
70     }
71     private IBinder binder;
72     /**
73      * 绑定的时候,调用service里的onBind方法,次方法有返回值,
74      * onServiceConnected获得onBind返回的binder
75      */
76     @Override
77     public void onServiceConnected(ComponentName name, IBinder binder) {
78         // TODO Auto-generated method stub
79         this.binder=binder;
80     }
81     @Override
82     public void onServiceDisconnected(ComponentName arg0) {
83         // TODO Auto-generated method stub
84         
85     }
86     
87 }

PlyMusicService:

 1 package com.example.service;
 2 
 3 import java.io.IOException;
 4 
 5 import com.example.practice5_service.R;
 6 
 7 import android.app.Service;
 8 import android.content.Intent;
 9 import android.media.MediaPlayer;
10 import android.os.Binder;
11 import android.os.Bundle;
12 import android.os.IBinder;
13 import android.util.Log;
14 
15 public class PlyMusicService extends Service {
16 
17     //private final String TAG=PlyMusicService.class.getSimpleName();
18     private final String TAG="PlyMusicService";
19     private MediaPlayer player;
20     //1
21     @Override
22     public void onCreate() {
23         // TODO Auto-generated method stub
24         Log.i(TAG,"Service-->onCreate" );
25         super.onCreate();
26         player=MediaPlayer.create(getApplicationContext(), R.raw.hhg);//创建MediaPlayer
27         player.setLooping(true);
28     }
29     
30     @Override
31     public void onDestroy() {
32         // TODO Auto-generated method stub
33         super.onDestroy();
34         Log.i(TAG,"Service-->onDestroy" );
35         if(player!=null&&player.isPlaying()){
36             player.stop();//停止
37         }        
38     }
39     //2 有返回值/状态,反复执行,
40     @Override
41     public int onStartCommand(Intent intent, int flags, int startId) {
42         // TODO Auto-generated method stub
43         Log.i(TAG,"Service-->onStartCommand" );
44         if(intent!=null){
45             //Bundle bundle=intent.getBundleExtra("info");
46             Bundle bundle=intent.getExtras();
47             String name=bundle.getString("name");
48             Log.i(TAG,"name-->"+name );
49         }
50         play();
51         return Service.START_STICKY;//意外关闭,重新启动
52         
53         //START_STICKY:service进程被kill掉,保留service状态为开始状态,但不保留intent对象,随后系统会尝试重新创建service
54         //START_NOT_STICKY:"非粘性",进程被kill掉,不会自动重启
55         //START_REDELIVER_INTENT:??
56         //默认super.onStartCommand(intent, flags, startId);
57     }
58         
59     
60     @Override
61     public IBinder onBind(Intent arg0) {
62         // TODO Auto-generated method stub
63         Log.i(TAG,"Service-->onBind" );
64         play();
65         return binder;
66     }
67     /**一个接口*/
68     private IBinder binder=new Binder(){
69         
70     };
71     
72     //取消绑定
73     @Override
74     public boolean onUnbind(Intent intent) {
75         // TODO Auto-generated method stub
76         Log.i(TAG,"Service-->onUnbind" );
77         return super.onUnbind(intent);
78     }
79     
80     private void play(){
81         try {
82             player.prepare();//准备
83         } catch (IllegalStateException e) {
84             // TODO Auto-generated catch block
85             e.printStackTrace();
86         } catch (IOException e) {
87             // TODO Auto-generated catch block
88             e.printStackTrace();
89         }
90         player.start();//播放
91     }
92     
93 }
原文地址:https://www.cnblogs.com/jiuqing/p/4074346.html