浅谈 Android服务的使用

服务是一种可以在后台执行耗时操作任务的不可见的Anroid四大组件之一,它可以IPC(跨进程通信)

为什么要有服务,用其他的子线程代替服务不行吗?

举个例子,从网络上下载信息更新的主界面上,4.0以后需要新开线程。如果不用服务,新开一个子线程,如果当前的主线程被系统杀掉或者用户退出了,子线程就失去控制了。而使用服务就避免了这个问题。

默认情况下,服务运行在主线程中,开启一个服务有两种方式:

首先,写一个类继承 service 然后 复写父类的方法

1.startService(这种API建议服务启动后自生自灭,与调用者没有任何联系)

Activity中通过 startService()方法开启一个服务,服务类会先执行 onCreate()-->onStartCommand()方法,在onStartCommand()方法中进行相关的操作,例如开启一个异步任务进行下载操作等等。注意onStartCommand()会返回一个Int类型的值,有以下几种类型:

1.1 START_NOT_STICKY(非粘性),意思是如果系统杀掉了这个service,那么系统不会重新去创建一个新的service实例,除非你给它重新发送一个intent去启动它。

1.2 START_STICKY(粘性),意思是如果系统杀掉了这个service实例,系统会重新创建并启动service,但是不会传递上一个intent,而是传一个空值

1.3 START_REDELIVER_INTENT,和第二种情况类似,但是会自动传递上一个intent

在执行完操作后,可以调用service自身的 stopSelf()或者使用activity中的stopService()方法结束一个服务,然后 service 会自动调用 destory()方法。

2.bindService(这种服务启动后,可以与调用者进行数据传递)

可以在Activity中通过 bindService()绑定一个服务,例如在 activity中的 OnStart()中绑定一个服务,

bindService()方法有三个参数,intent,   serviceConnection对象,服务启动类型,其中的serviceConn对象需要new 出来,创建时要重写onServiceConnected() onServiceDisConnected(),其中onServiceConnected()有参数中传递一个IBinder类型的对象,这个对象是绑定的service实例启动时调用 onBind()方法返回的对象,这样也就实现了绑定类型的service可以回传数据的功能。

另外,多个组件可以同时绑定一个service,解绑使用unBindService(),当service全部解绑后,调用serviceonDestory()方法结束其生命周期。

因为service默认运行在主线程中,它不会自动去创建一个子线程,所以,当在service中进行耗时操作的时候,要开启子线程

另外还有一种service叫做  IntentService ,它是运行在子线程中的,这种比较适合单线程操作(非高并发),它一次只能处理一个线程传递过来的操作,只需要复写它的onHandlerIntent()方法即可

intentService操作流程:

1.开启子线程去处理从 startCommand()方法中传递过来的intent

2.创建工作队列去维护传递过来的intent

3.处理完所有的intent后自动停止服务,不需要你去调用 stopSelf()方法

4.onStartCommand()onBind()都已经在内部写好,不需要你再重写了,你只需要重写 onHandlerIntent()

为什么service可以进行IPC

答:绑定的service中有 onBind()方法,这个方法返回一个iBinder接口的实现对象,而在另一端的 ServiceConnection类的创建中有 onServiceConnected()方法,这个方法接收一个iBander对象,而这个对象就是从远端的 onBind()中返回的。

IBinder接口中有 transact()方法,不要直接使用这个接口,而要通过继承 Binder类来间接使用,

Transact()有一个参数 Parcel,这个parcel是一个轻量级的远程通信解决方案的缓冲流,它除了可以通过write写入数据,通过read读取数据外,还持有调用它的binder的引用,这样当一个进程的binder调用 transact()方法时,持有原binder引用去跨进程。调用 transact()方法时,transact()里面套用了binderonTransact()方法,前一个方法里面的参数转移到了后一个方法参数中,当后一个方法处理完后,前一个方法继续执行并返回结果。这样保证了事务的原子性。所以在进行这样的操作的时候,当前的进程是要被堵塞的。

IBinder是远程IPC调用的一个轻量级的高效的解决方案。

具体做法:

AB传递数据,B接到数据处理后回传给A

1.B中定义一个公共的类继承Binder,并重写onTransact()方法,并将这个内部类定义成B的成员变量,在BonBind()方法中返回这个成员变量

2.A中绑定好 service ,拿到从 serviceConnected()返回的参数 binder 对象,在该调用的时候调用 binder.transact()方法,定义一个parcel传入数据,定义另一个 parcel接收返回的数据,并把他们当做参数传入 transact()中,然后等待方法执行即可。


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