Android执行Service有两种方法,一种是startService,一种是bindService。下面让我们一起来聊一聊这两种执行Service方法的区别。

1、生命周期上的区别

执行startService时,Service会经历onCreate->onStartCommand。当执行stopService时,直接调用onDestroy方法。调用者如果没有stopService,Service会一直在后台运行,下次调用者再起来仍然可以stopService。

执行bindService时,Service会经历onCreate->onBind。这个时候调用者和Service绑定在一起。调用者调用unbindService方法或者调用者Context不存在了(如Activity被finish了),Service就会调用onUnbind->onDestroy。这里所谓的绑定在一起就是说两者共存亡了。

多次调用startService,该Service只能被创建一次,即该Service的onCreate方法只会被调用一次。但是每次调用startService,onStartCommand方法都会被调用。Service的onStart方法在API 5时被废弃,替代它的是onStartCommand方法。

第一次执行bindService时,onCreate和onBind方法会被调用,但是多次执行bindService时,onCreate和onBind方法并不会被多次调用,即并不会多次创建服务和绑定服务。

2、调用者如何获取绑定后的Service的方法

onBind回调方法将返回给客户端一个IBinder接口实例,IBinder允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。我们需要IBinder对象返回具体的Service对象才能操作,所以说具体的Service对象必须首先实现Binder对象。

3、既使用startService又使用bindService的情况

如果一个Service又被启动又被绑定,则该Service会一直在后台运行。首先不管如何调用,onCreate始终只会调用一次。对应startService调用多少次,Service的onStart方法便会调用多少次。Service的终止,需要unbindService和stopService同时调用才行。不管startService与bindService的调用顺序,如果先调用unbindService,此时服务不会自动终止,再调用stopService之后,服务才会终止;如果先调用stopService,此时服务也不会终止,而再调用unbindService或者之前调用bindService的Context不存在了(如Activity被finish的时候)之后,服务才会自动停止。

那么,什么情况下既使用startService,又使用bindService呢?

如果你只是想要启动一个后台服务长期进行某项任务,那么使用startService便可以了。如果你还想要与正在运行的Service取得联系,那么有两种方法:一种是使用broadcast,另一种是使用bindService。前者的缺点是如果交流较为频繁,容易造成性能上的问题,而后者则没有这些问题。因此,这种情况就需要startService和bindService一起使用了。

另外,如果你的服务只是公开一个远程接口,供连接上的客户端(Android的Service是C/S架构)远程调用执行方法,这个时候你可以不让服务一开始就运行,而只是bindService,这样在第一次bindService的时候才会创建服务的实例运行它,这会节约很多系统资源,特别是如果你的服务是远程服务,那么效果会越明显(当然在Servcie创建的是偶会花去一定时间,这点需要注意)。

4、本地服务与远程服务

本地服务依附在主进程上,在一定程度上节约了资源。本地服务因为是在同一进程,因此不需要IPC,也不需要AIDL。相应bindService会方便很多。缺点是主进程被kill后,服务变会终止。

远程服务是独立的进程,对应进程名格式为所在包名加上你指定的android:process字符串。由于是独立的进程,因此在Activity所在进程被kill的是偶,该服务依然在运行。缺点是该服务是独立的进程,会占用一定资源,并且使用AIDL进行IPC稍微麻烦一点。

对于startService来说,不管是本地服务还是远程服务,我们需要做的工作都一样简单。

5、代码实例

startService启动服务

publicclassLocalService1extendsService{/***onBind是Service的虚方法,因此我们不得不实现它。*返回null,表示客服端不能建立到此服务的连接。*/@OverridepublicIBinderonBind(Intentintent){returnnull;}@OverridepublicvoidonCreate(){super.onCreate();}@OverridepublicvoidonStartCommand(Intentintent,intstartId,intflags){super.onStartCommand(intent,startId,flags);}@OverridepublicvoidonDestroy(){super.onDestroy();}}

bindService绑定服务

publicclassLocalServiceextendsService{/***在LocalService中我们直接继承Binder而不是IBinder,因为Binder实现了IBinder接口,这样我们可以**少做很多工作。*/publicclassSimpleBinderextendsBinder{/***获取Service实例*@return*/publicLocalServicegetService(){returnLocalService.this;}publicintadd(inta,intb){returna+b;}}publicSimpleBindersBinder;@OverridepublicvoidonCreate(){super.onCreate();//创建SimpleBindersBinder=newSimpleBinder();}@OverridepublicIBinderonBind(Intentintent){//返回SimpleBinder对象returnsBinder;}}

上面的代码关键之处,在于 onBind(Intent) 这个方法 返回了一个实现了 IBinder接口的对象,这个对象将用于绑定Service 的 Activity 与 Local Service 通信。

下面是 Activity 中的代码:

publicclassMainextendsActivity{privatefinalstaticStringTAG="SERVICE_TEST";privateServiceConnectionsc;privatebooleanisBind;@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);sc=newServiceConnection(){@OverridepublicvoidonServiceDisconnected(ComponentNamename){}@OverridepublicvoidonServiceConnected(ComponentNamename,IBinderservice){LocalService.SimpleBindersBinder=(LocalService.SimpleBinder)service;Log.v(TAG,"3+5="+sBinder.add(3,5));Log.v(TAG,sBinder.getService().toString());}};findViewById(R.id.btnBind).setOnClickListener(newOnClickListener(){@OverridepublicvoidonClick(Viewv){bindService(newIntent(Main.this,LocalService.class),sc,Context.BIND_AUTO_CREATE);isBind=true;}});findViewById(R.id.btnUnbind).setOnClickListener(newOnClickListener(){@OverridepublicvoidonClick(Viewv){if(isBind){unbindService(sc);isBind=false;}}});}}


6、在AndroidManifest.xml里Service元素常见选项

android:name  -------------  服务类名

android:label  --------------  服务的名字,如果此项不设置,那么默认显示的服务名则为类名

android:icon  --------------  服务的图标

android:permission  -------  申明此服务的权限,这意味着只有提供了该权限的应用才能控制或连接此服务

android:process  ----------  表示该服务是否运行在另外一个进程,如果设置了此项,那么将会在包名后面加上这段字符串表示另一进程的名字

android:enabled  ----------  表示是否能被系统实例化,为true表示可以,为false表示不可以,默认为true

android:exported  ---------  表示该服务是否能够被其他应用程序所控制或连接,不设置默认此项为 false




更多相关文章

  1. Android常用固件修改
  2. Android(安卓)ActionBar完全解析(下)
  3. Android应用数据存储几种方式(2)
  4. 12.2 HTTP请求
  5. 【Android(安卓)P】 JobScheduler服务源码解析(二) ——框架解析
  6. Android——使用ContentProvider在应用间传递数据
  7. android 8.0 报错StartForeground Bad Notification Error 解决
  8. Android(安卓)fragment 重叠问题,闪退后fragment重叠bug解决方法
  9. Android入门笔记 - 网络通信 - HttpClient

随机推荐

  1. csr8811蓝牙芯片porting总结
  2. Android常用控件之悬浮窗(Service实现)
  3. EditText 的常用属性与解释
  4. Android(安卓)2.2兼容性移植
  5. android通用文件操作
  6. Android开机广播和关机广播
  7. Android(安卓)LCD(三):Samsung LCD接口篇
  8. android 为摄像头增加闪光灯(s5pv210)
  9. Conversion to Dalvik format failed: Un
  10. Android各大发布市场