**Service**
Service与Activity一样,是Android的四大组件之一。Activity是看得见的,而Service则是看不见的。看得见的Activity一般承担显示界面、控制的功能,而Service则承担后台任务。而Service与线程的区别在于,Service是Android的四大组件之一,所以系统不会轻易将其杀死。服务可有其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信(IPC)。例如,服务可以处理网络事务、播放音乐、执行文件I/O或与内容提供程序交互,而所有这一切均可在后台进行。
服务基本上分为两种形式运行:
- 启动
当应用组件(如Activity)通过调用startService()启动服务时,服务即处于“启动”状态。一旦启动,服务即可在后台无限期运行,即使启动服务的组件已被销毁也不受影响。已启动的服务通常是执行单一操作,而且不会将结果返回给调用方。例如,它可能通过网络下载或上传文件。操作完成后,服务会自行停止运行。
- 绑定
当应用组件通过bindService()绑定到服务时,服务即处于“绑定”状态。绑定服务提供了一个客户端-服务器接口,允许组件与服务进行交互、发送请求、获取结果,甚至是利用进程间通信(IPC)跨进程执行这些操作。仅当与另一个应用组件绑定时,绑定服务才会运行。多个组件可以同时绑定到该服务,但全部取消绑定后,该服务即会被销毁。
##startService()
1.启动后,服务就和启动它的组件没关系
2.如果服务被意外,隔段时间会自动重启,随着被杀死的次数增多,间隔时间越来越久
3.生命周期方法在主线程调用
4.服务要和子线程配合
5.生命周期:onCreate()-->onStartCommand()--onDestroy();,如果重复启动一个service,onCreate()方法不会再调用,直接onStartCommand()
如果Service还没有运行,则android先调用onCreate()然后调用onStart();
如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。 调用stopService的时候直接onDestroy,
如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。
该Service的调用者再启动起来后可以通过stopService关闭Service。
所以调用startService的生命周期为:onCreate --> onStart(可多次调用) --> onDestroy
对于bindService()绑定回调Service会经历:
context.bindService()->onCreate()->onBind()->Service running-->onUnbind() -> onDestroy() ->Service stop
onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。
这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,
Srevice就会调用onUnbind->onDestroy相应退出。
所以调用bindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。
一但销毁activity它就结束,如果按home把它放到后台,那他就不退出。
在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。
Service 类两种启动方法:
1. Context.startService():
在同一个应用任何地方调用 startService() 方法就能启动 Service 了,然后系统会回调 Service 类的 onCreate() 以及 onStart() 方法。这样启动的 Service 会一直运行在后台,直到 Context.stopService() 或者 selfStop() 方法被调用。
另外如果一个 Service 已经被启动,其他代码再试图调用 startService() 方法,是不会执行 onCreate() 的,但会重新执行一次 onStart() 。
2. Context.bindService() :
将 Service 和调用 Service 的客户类绑起来,如果调用这个客户类被销毁,Service 也会被销毁。用这个方法的一个好处是,bindService() 方法执行后 Service 会回调上边提到的 onBind() 方发,你可以从这里返回一个实现了 IBind 接口的类,在客户端操作这个类就能和这个服务通信了,比如得到 Service 运行的状态或其他操作。如果 Service 还没有运行,使用这个方法启动 Service 就会 onCreate() 方法而不会调用 onStart()。
** 2.工作中遇到的安卓下线程与服务的区别:**
1.进程和服务的定义
线程(thread):线程是程序运行的最小单元,是分配cpu的基本单位,本应用程序托管。
服务(service);是android的一种机制,对应的service是运行在主线程上的,它是由系统进程托管。他们之间的通信类似于client和server,是一种轻量级的ipc通信,这种通信的载体是binder,它是在linux层交换信息的一种ipc;
1)在应用中,如果是长时间的在后台运行,而且不需要交互的情况下,使用服务。
同样是在后台运行,不需要交互的情况下,如果只是完成某个任务,之后就不需要运行,而且可能是多个任务,需要长时间运行的情况下使用线程。
2)如果任务占用CPU时间多,资源大的情况下,要使用线程。
3)最优的使用方法
创建并启动一个service,在Service里面创建、运行并控制该Thread(因为任何Activity都可以控制同一个Service,而系统只会创建一个对应的Service的实例)还有个办法是使用IntentService,它里面自带了子线程,使用它就不用创建新线程了。
但由于是单个的worker thread,所以任务需要排队,不适合大多数的多任务情况。
最后可以把Service想象成一种消息服务,而你可以在任何有Context的地方调用Context.startservice、Context.stopservice、Context.bindService,Context.unbindService,来控制它,也可以在Service里注册BroadcastReceiver,在其他地方通过发broadcast来控制它。
生命周期
1)startService生命周期
oncreate()------onStartCommand()-----onDestroy()
如果重复启动一个服务,oncreate()只走一次,只调用onStartCommand()
2)bindService生命周期
oncreate()----onBind()----onUnBind()
绑定后跟组件生命周期绑定
3)混合启动生命周期
1.先启动后绑定
oncreate()---onStartCommand()----onBind()----onUnBind()
解绑后,不会走onDestroy()方法,因为startService还在使用这个服务
2.先绑定后启动
oncreate()----onBind()----onStartCommand()----onUnBind()----onDestroy()
方法
使用intent跳转
starteService()启动服务
stopeService()停止服务
bindService()绑定服务,需要三个参数,第一个是intent,第二个参数为服务连接器ServiceConnection,第三个参数BIND_AUTO_CREATE
unBindService()解绑服务
通信
service---->Activity
在service中,写一个内部类继承Binder,在内部类写一个方法,在onBind()方法返回我们得内部类。在Activity页面,我们bindService()服务连接器回调中,在onServiceConnected强制转换对应的service,调用服务方法
mConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//服务连接成功之后的回调
//IBinder service,这个对象是要绑定的服务里面的onBind()的返回值
MyService.MyBinder binder = (MyService.MyBinder) service;
//这样就可以调用到服务里面的方法
binder.call();
}
@Override
public void onServiceDisconnected(ComponentName name) {
//服务断开连接的回调
}
};