一、简介
Android中service(服务)运行于后台,没有界面。和其他组件一样,service也运行在主线程中,因此不能用它来做耗时的请求或者动作。可以在服务中开启线程,在线程中做耗时操作。可以启动一个服务service来播放音乐,或者记录地理信息位置的改变,或者启动一个服务来运行并一直监听某种动作。
二、Service的种类
服务一般分为两种:
1、本地服务,Local Service用于应用程序内部。
在Service可以调用Context.startService()启动,调用Context.stopService()结束。在内部可以调用Service.stopSelf() 或Service.stopSelfResult()来停止。无论调用了多少次startService(),都只需调用一次stopService()来停止。调用startForeground()方法可以将服务运行于前台并在通知栏展示。
2、远程服务,Remote Service用于android系统内部的应用程序之间。
可以定义接口并把接口暴露出来,以便其他应用进行操作。客户端建立到服务对象的连接,并通过那个连接来调用服务。调用Context.bindService()建立连接并启动,调用Context.unbindService()关闭连接。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。提供给可被其他应用复用,比如定义一个天气预报服务,提供与其他应用调用即可。
三、Service的简单使用
1、startservice方法
(1)、自定义类继承系统Service,复写生命周期方法,在AndroidManifest.xml文件中通过service标签注册自定义服务
/** * 创建Service的步骤: * 1、自定义类继承系统Service * 2、复写生命周期方法 * 3、在AndroidManifest.xml文件中通过service标签注册自定义服务 * * 注意:Service在Application中是一全局的方式存在 * */ public class MyService extends Service{ /** * 创建Service时被调用 * 此方法在一个Service的生命周期中只会别调用一次 * 一般在此方法中初始化数据 */ @Override public void onCreate() { super.onCreate(); android.util.Log.e("danny", "MyService--onCreate"); } /** * 每次调用startService时都会调用此方法 * @param intent 就是startService时所使用的intent对象 * 根据此方法的返回值,决定所创建的Service是否是粘性服务 * START_NOT_STICKY 非粘性服务 * START_STICKY 粘性不带记忆服务 * START_REDELIVER_INTENT 粘性带记忆服务 * 一般在此方法中开启线程做耗时操作 */ @Override public int onStartCommand(Intent intent, int flags, int startId) { android.util.Log.e("danny", "MyService--onStartCommand"); String threadName = Thread.currentThread().getName(); android.util.Log.e("danny", "threadName is " + threadName); new Thread(){ public void run() { for(int i = 0; i < 10; i++){ try { Thread.sleep(1000); android.util.Log.e("danny", "执行到 " + i); } catch (InterruptedException e) { e.printStackTrace(); } } Intent broad = new Intent(); broad.setAction("MyBroadcas"); sendBroadcast(broad); }; }.start(); return START_REDELIVER_INTENT; } /** * 此方法跟启动服务没有任何关系,只跟绑定服务有关 */ @Override public IBinder onBind(Intent intent) { android.util.Log.e("danny", "MyService--onBind"); return null; } /** * 当Service被销毁时调用此方法 * Service销毁的情况; * 1 Activity.stopService * 2 Service.stopSelf() */ @Override public void onDestroy() { android.util.Log.e("danny", "MyService--onDestroy"); super.onDestroy(); } }
(2)、调用startService方法启动服务;停止时调用stopService方法停止服务
case R.id.startService: /* * startService启动Service的步骤 * 1、创建启动服务的Intent对象,并指定目标Service * 2、Context.startServie方法启动服务,并传递Intent对象 * * 特点: * 通过startService启动的服务不会跟Activity进行绑定 * 当销毁Activity时,Service不会被自动销毁 */ Intent intent = new Intent(this, MyService.class); startService(intent); break; case R.id.stopService: Intent stopIntent = new Intent(this, MyService.class); stopService(stopIntent); //调用Context.stopService方法停止目标Service break;
2、bindService方法
(1)、自定义类继承系统Service,复写生命周期方法,在AndroidManifest.xml文件中通过service标签注册自定义服务
/** * 通过bindService绑定的服务 * 生命周期:onCreate onBind onUnBind onDestroy * */ public class MusicService extends Service { /** * 创建服务时被调用,此方法在一个生命周期中只会被调用一次 */ @Override public void onCreate() { super.onCreate(); } /** * 当第一次调用bindService时,此方法被调用 * note:如果一个服务已经被绑定,则不会被再辞绑定 * @param intent 调用bindService时所传递的Intent对象 * @return 返回给bindService中ServiceConnection接口参数 */ @Override public IBinder onBind(Intent intent) { return new MyBinder(); } /** * 当调用UNBindService解绑定一个服务时,此方法被调用 * @param intent * @return */ @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } /** * 当服务被销毁时此方法被调用 */ @Override public void onDestroy() { super.onDestroy(); } private MediaPlayer player; class MyBinder extends Binder { /** * 实现音乐播放的效果 */ public void play(){ if(player == null) { player = MediaPlayer.create(MusicService.this, R.raw.hitta); player.start(); } else if(!player.isPlaying()) { player.start(); } } /** * 实现音乐暂停的效果 */ public void pause() { if(player != null && player.isPlaying()) { player.pause(); } } /** * 实现音乐停止的效果 */ public void stop(){ if(player != null) { player.stop(); player = null; } } } }
(2)、bindService方法绑定服务,调用unbindService方法解绑服务
public class MainActivity extends Activity { private MyBinder mBinder; //声明并创建绑定服务的连接回调接口 //此接口中包含了绑定服务时的回调函数 private ServiceConnection conn = new ServiceConnection() { /** * 当服务因异常被断开连接时调用此方法 * 参数是被绑定的服务组件名称 */ @Override public void onServiceDisconnected(ComponentName name) { } /** * 当绑定服务连接上,并且返回具体IBinder对象时此方法被调用 * 第一个参数 绑定服务的组件名称 * 第二个参数 在绑定服务的onBind方法返回的IBinder对象 */ @Override public void onServiceConnected(ComponentName name, IBinder service) { Toast.makeText(MainActivity.this, "服务绑定成功", Toast.LENGTH_SHORT).show(); //将Service的onBind方法中返回的IBinder对象保存 //后续可以调用此Binder中的方法 mBinder = (MyBinder) service; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* * 通过bindService绑定目标Service * 绑定服务会跟Activity进行绑定,当Activity被销毁时,此Activity所绑定的服务也会被销毁 */ // 1 创建Intent意图,并指定目标Service Intent intent = new Intent(this, MusicService.class); bindService(intent, conn, BIND_AUTO_CREATE); } public void btnClicked(View view) { //添加判断条件,判断服务之前时候绑定成功 if(mBinder == null) { Toast.makeText(this, "服务没有被绑定", Toast.LENGTH_SHORT).show(); return; } switch (view.getId()) { case R.id.play: mBinder.play(); break; case R.id.pause: mBinder.pause(); break; case R.id.stop: mBinder.stop(); break; default: break; } } }