interView - Service

来源:互联网 发布:mac系统照片图库打不开 编辑:程序博客网 时间:2024/05/29 17:51

1.什么是service?

service不是线程也不是进程,service运行在主线程上,是一个抽象的context,是从逻辑上表示一个用来执行长期运行的后台任务或功能的一个组件。


2.为什么要使用service?

对于activity这种活跃周期相对短暂的组件而言,一旦用户切换到其它应用,activity就会被pause,stop,甚至会被destroy,不能在后台处理其它事务。需要强调的是,严格来说你仍然可以在activity里创建work thread或者asyncTask之类做后台的事情,但是这样做没有保障,因为一旦你所有的activity被切换到后台,系统随时会kill掉你的process,你的后台任务随时可能悄无生气的死掉。

Android为什么要这样设计?windows下面的窗口在最小化的时候不是一样可以处理消息或者继续运行吗?这是另外一个话题,不过回答也很简单:这是移动设备,内存/电池都有限。

对你的应用而言,通过在manifest里声明service,把需要后台长期运行的逻辑放在service里,你便获得了这样的保障:只要系统内存不是极端不够用,你的service一定不会被kill掉。对系统而言,当看到一个进程里有service在运行,这个进程就具有较高的优先级,会在内存不足被杀的行列里排的比较靠后。

可是前面不是强调了service并不等同于process或者thread吗?为什么上面又在说杀进程什么的?这里再次强调,你可以把service看作一坨代码,用来在后台做些事情,仅此而已。至于这坨代码在哪里运行,完全是取决于你自己的喜好。你的local service,如果不建立thread,仍然是在你的应用进程的主线程即UI线程里运行。如果你不想阻塞UI线程,你就创建一个work thread。但这些细节android frameWork并不怎么关心,它只知道你创建了一个service,然后在你mianfest里面找到这个service是声明在哪个process里运行,那么这个process就不容易被kill。

什么时候选择local service(即不执行额外的进程),什么时候选择remote service(额外的进程)?通过我们会把真的长期运行的service(例如IM之类)放在单独的进程里,这样UI所在的进程在必要的时候仍然可以被系统kill掉来腾出内存。而local service通常用来处理一些短期运行但仍然超过activity活动周期的任务,打个比方,发送短信或彩信。这样的任务执行完以后,service就可以stop自己,仍然不妨碍整个UI进程被回收掉。



3.service生命周期

服务有两种启动方式,第一种是通过startService方式,通过stopService停止,服务一旦开启就与调用者没有任何关系,就是调用者的Activity即便退出了,也不会影响后台的service运行。其生命周期为context.startService() ->onCreate()- >onStart()->Service running-->context.stopService() | ->onDestroy() ->Service stop 。

如果Service还没有运行,则android先调用onCreate()然后调用onStart()。

如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。 stopService的时候直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。该Service的调用者再启动起来后可以通过stopService关闭Service。所以调用startService的生命周期为:onCreate --> onStart(可多次调用) --> onDestroy


第二种是通过绑定方式bindService开启服务,通过unbindService方法停止服务一旦调用者(Activity)退出了,那他绑定的服务也会跟着退出.
通过绑定方式开始的服务,我们可以在Activity里面调用服务里面的方法,利用ServiceConnection节口,返回一个ibinder对象,拿着ibinder对象获取到服务里面的
引用(自定义一个接口信息,在服务里继承Binder再实现自定义接口)来调用服务里的方法

对于bindService()启动Service会经历:
context.bindService()->onCreate()->onBind()->Service running-->onUnbind() -> onDestroy() ->Service stop
onBindr将返回给客户端一个IBindr接口实例,IBindr允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。
这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。 

所以调用bindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。
一但销毁activity它就结束,如果按home把它放到后台,那他就不退出。
服务只能被解除一次,多次解除绑定服务,程序会出现异常,重写onDestroy,调用方法
unbindService(conn)则可避免这个问题.

 一个 Service 如果是通过 bindService() 启动的,那么它会一直存在到没有任何客户端与它保持连接为止,原因是可能有很多客户端与这个服务保持连接,这时如果某个链接被客户端主动断掉只会是 Service 的链接数减 1 ,当减至 0 的时候这个 Service 就会被销毁。
补充:
在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),
其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。


0 0
原创粉丝点击