android ApiDemo学习(一)service总结

参考官网:http://developer.android.com/reference/android/app/Service.html

 

1.what is service:

  • 两个不是:

-service不是一个单独的进程,运行在应用程序所属的进程里——除非:AndroidManifest.xml声明service时显示属性:android:process=":remote"

-service不是一个单独的线程,但是可以脱离主线程工作——为了避免“应用程序无响应”的错误

默认:service在后台运行在主线程里(UI线程)

  • 两个是:

-service可以是:应用程序告诉系统,它想放一些东西在后台运行。这时的service由系统管理,直到有人(包括service自己)显式调用stopService或stopSelf把service停止。——startService

-service可以是:应用程序向别的应用程序展示一些功能。这时service长期绑定在这个应用上,可以与这个应用进行交互。——bindService

 

2.生命周期:

可以看出,有两种方式获得service,一是startService,一是bindService

  • startService方式:

-startService()开启服务:service先onCreate,然后onStartCommand。如果再次startService,service只执行onStartCommand,不再执行onCreate

-stopService()或stopSelf()停止服务:service进入onDestroy。无论service被startService()多少次,由于并没有执行onCreate,说明每次start的都是同一个service,因此只需要一次onDestroy就把这个service停止了。

  • bindService方式:

-bindService()绑定服务:如果service没有还没有create,那么进入onCreate,然后onBind。否则直接进入onBind。

-unbindService()解除绑定:如果service没有别的应用绑定,只是自己退出而已。如果是最后一个关联的应用解除绑定,那么service进入onUnbind。当这个service没有应用绑定,也没有应用start,那么这个service就onDestroy。

 

3. bindService方式:

bindService方式有点罗嗦,这里单独讲下。

  • 连接:

由于bindService是application和service建立了一个连接,为了双方的交互,所以客户端application需要提供一个ServiceConnection的对象。提供两个函数:onServiceConnected和onServiceDisconnected,分别表示当连接建立和断开时回调。因此,可以重写这两个函数来实现自定义操作。

  • 那么双方究竟如何交互的呢:

客户端bindService后,服务器端会进入onBind。onBind返回一个IBinder对象,这个对象会返回给客户端。返回到哪里呢?就是onServiceConnected的参数IBinder。可以输出service端和client端的这两个IBinder,可以看到是一样的。也就是说,双方靠这个IBinder对象进行交互!

怎么交互呢?

-服务端自定义一个类继承Binder,这个Binder类中自定义一些方法。

-onBind中将这个Binder自定义类的对象返回。

-客户端的onServiceConnected函数中,从参数得到这个IBinder对象。

-客户端可以直接使用这个IBinder对象调用服务端Binder类的自定义方法。这样就客户端就可以调用服务端的方法啦!

 

4. Remote Service

service和client在同一个进程内,就是localservice,不在同一个进程,就是remoteservice。

  • 定义service是remote service:

AndroidMenifest.xml中声明Service时,添加属性,android:process=":remote"

  • startService与BindService:

start一个remote Service和start一个local Service没有本质区别。因为application和service不需要交互,start之后各自运行各自的,所以很简单, 下文不再讲述。

bind一个remote Service和bind一个local Service不同。local service可以返回一个IBinder对象供client使用,从而完成两者的交互。remote service则需要使用AIDL方式来完成交互。

  • client与remote service进行交互:

(1)AIDL方式:AIDL——android interface definition language

原理:

公共端:定义接口文件myinterface.aidl,这个接口是公共的,要放在service和client的src下。

service:定义stub实现myinterface中声明的方法。stub相当于代理。

client端:可以远程调用myinterface.aidl中声明的方法,这些方法的实际执行是在service端。

 

那么service和client是如何联系起来的呢?和local service一样,通过onBind函数的返回值!

首先:service顶一个接口Stub类型的对象,实现myinterface.aidl中的方法。

接着:service在onBind中返回Stub类型的对象,这时这个对象是IBinder类型。

然后:client在ServiceConnection的onServiceConnected函数中的参数获得service传过来的IBinder对象。

最后:client使用myinterface.stub.asInterface(IBinder对象)函数将这个IBinder转化为AIDL接口类型。

可以看到,remote service和local service类似,使用这个共同的IBinder对象交互!不同的是,需要把这个对象在IBinder类型和AIDL接口类型之间做下转换。

 

local service中,client调用service提供的方法,这些方法的定义就在IBinder类中。即,声明和定义都在service端。

remote service中,client调用service提供的方法,这些方法的声明在它们共有的AIDL文件里,定义在service端的stub对象里。

 

(2)Messenger方式:

原理:

service:定义Handler处理client请求,使用这个Handler创建Messenger_s_receive,使用这个Messenger_s_receive创建IBinder对象,将这个对象在onBind函数中返回。

client端:ServiceConnection的onServiceConnected函数的参数中获得service传过来的IBinder对象,始终这个IBinder对象创建Messenger_c_send。

——Messenger_s_receive用于service接收消息,Messenger_c_send用于client发送消息

client端:定义Handler处理service请求,使用这个Handler创建Messenger_c。使用Messenger_c_send向service发送消息时,注册Messenger_c。

service:Handler中处理client请求,保存client发送的消息为“注册”的Messenger(就是Messenger_c),使用这个保存的Messenger向client端发送消息。

——Messenger_c用于service向client发送消息,也用于client从service接收消息

 

总结:无论是AIDL方式,还是Messenger方式;无论是local service还是remote service。service和client的联系最终都是通过IBinder对象连接起来的。因此,service端的onBind函数的返回值非常重要!归根到底,进程间的通讯是由Binder实现的!

你可能感兴趣的:(c,android,service,服务器,application,interface)