Started Service 与 Bound Service

主要说明Started Service与Bound Service的区别于联系。

一:基本用法

Stared Service
对于一个Component对象,调用startService(Intent aIntent)来启动一个Service

启动之后,在Service里面onStartCommand(Intent intent,int flags,int startId)方法里面的Intent就是startService(Intent aIntent)传入的aIntent对象(startId参数的说明:因为一个Service可能处理多个request,所以多次调用startService()就会产生一个startId,并且是从1开始的。。。。原文如下:you handle each call to onStartCommand()yourself, you can perform multiple requests simultaneously,flags参数的说明:暂时还没搞懂)

Started Service由于是一直在运行,像音乐播放器,可以用前台服务(Service in the Foreground)调用startForeground(int id, Notification notification)即可,System一般在内存不足的时候不会先回收前台服务。因为前台服务有焦点把,我估计是这样的。

Bound Service
对于一个Component对象,调用bindService(Intent aIntent)来绑定一个Service

绑定之后,在Service里面onBind(Intent intent)里面Intent就是bindService(Intent aIntent)中的aIntent对象。

二:生命周期

Stared Service
当调用startService()的完成后,该方法立即返回,然后Android System调用ServiceonCreate()方法(只在第一次的时候调用),然后再调用onStartCommand()方法,这时Service进入Active Lifetime。然后该Service无限的运行下去,直到Service内部调用stopSelf()或者一个Component调用startService()。这时进入stopped状态,之后系统就会destroys it。

Bound Service
当调用bindService()的完成后,该方法立即返回,然后Android System调用ServiceonCreate()方法(只在第一次的时候调用),然后再调用onBind()方法。如果绑定成功的话,调用ServiceConnectiononServiceConnected(ComponentName name, IBinder service)方法。


Service进入stopped状态是由以下2中原因造成的

  • 当所有的Client都调用unbindService()之后。
  • 当所有的Client都被系统destroys之后(例如Activity对象onDestroy()执行过后,就会调用ServiceonDestroy()方法)。
    这意味着多个Client可以绑定同一个Service

三:与Activity通信
1.通过Ibinder对象
2.通过回调接口
3.通过Broadcast

参照2篇文章 (有详细的说明)

  • http://blog.csdn.net/xiaanming/article/details/9750689#reply
  • https://stackoverflow.com/questions/6099364/how-to-use-pendingintent-to-communicate-from-a-service-to-a-client-activity/8029533#8029533

对于第二篇文章的一些说明Google文档如下说:

If the service does not also provide binding, the intent delivered with startService() is the only mode of communication between the application component and the service. However, if you want the service to send a result back, then the client that starts the service can create a PendingIntent for a broadcast (with getBroadcast()) and deliver it to the service in the Intent that starts the service. The service can then use the broadcast to deliver a result.

StackOverflow回答的一些理解:

public class DataRequestService extends Service {

   private final class ServiceHandler extends Handler {
      public ServiceHandler(Looper looper) {
         super(looper);
      }

      @Override
      public void handleMessage(Message msg) {
         log.info("handleMessage");
         //... performing some time-consuming operation 
         Bundle bundle = msg.getData();
         PendingIntent receiver = bundle.getParcelable("receiver");
         // Perform the operation associated with PendingIntent
         try {            
            //you can attach data from the operation in the intent.
            Intent intent = new Intent();
            Bundle b = new Bundle();
            //b.putString("key", value);
            intent.putExtras(b);
            receiver.send(getApplicationContext(), status, intent);
         } catch (CanceledException e) {         
         e.printStackTrace();
         }         
      }
   }

   @Override
   public void onStart(Intent intent, int startId) {
      Bundle bundle = intent.getExtras();
      msg.setData(bundle);
      mServiceHandler.sendMessage(msg);
   }
Intent serviceIntent = new Intent(context, DataRequestService.class);   
   @Override
   public void onClick(View v) {
      //this is the intent that will be broadcasted by service.
      Intent broadcastReceiverIntent = new Intent(context, DataBroadcastReceiver.class);      
      //create pending intent for broadcasting the DataBroadcastReceiver
      PendingIntent pi = PendingIntent.getBroadcast(context, 0, broadcastReceiverIntent, 0);      
      Bundle bundle = new Bundle();            
      bundle.putParcelable("receiver", pi);
      //we want to start our service (for handling our time-consuming operation)
      Intent serviceIntent = new Intent(context, DataRequestService.class);
      serviceIntent.putExtras(bundle);
      context.startService(serviceIntent);
   }

首先,PendingInten是对Intent的一个包装,因为传递进来的PendingIntent是有PendingIntent.getBroadcast()得到的,所以在send()方法的时候,就相当于startBroadcast(),也就达到了Service => Activity的消息的传递。

四:高级用法

关于AIDL与IPC的知识,正在学习中。。。

你可能感兴趣的:(android,service)