大家好,今天我来给大家讲解一下在安卓面试当中有关service的面试问题,我把自己的理解写出来,可能有不足的地方,多加体谅
一、service的应用场景,以及和Thread的区别
一.service基础
1.service是什么?
service在安卓里面,作为四大组件之一,它扮演着非常重要的角色,它可以在后台处理一些耗时的逻辑,或者你可以用它去执行一些需要长时间运行的任务,可以在后台开启.必要的时候,我们甚至可以在程序退出的时候,仍能让service在后台继续保持运行状态,这就是我们这些年听到的service保活.
所以说:Service(服务)是一个一种可以在后天执行长时间运行操作而没有用户界面的应用组件
注:service 可以由其他应用组件,比如说activity等等来启动,服务一旦被启动后,都将在后台一直运行,即使启动它的activity以及被销毁了,也不会受到影响.另外你也可以把Service绑定到activity,然后可以让activity和service直接进行数据交互.甚至由于service和activity有可能是在不同的进程里面,你也可以通过进程间通信,来进行数据之间的传输.我们需要注意的是,service和广播Broadcast有一个共同点,就是他们都是运行在主线程当中,所以说在这个里面都不能做长时间的耗时操作,这里必须特别注意一下.还有一点:service里面不能做耗时操作,一定要记住.
2.service和Thread的区别
一.定义
首先我们来看Thread,它是程序执行的最小单元所以说你可以用它来执行一些异步操作.而service是安卓的一种机制,当它运行的时候,如果它是本地的service,那么它对应的service是运行在主线程上的,也就是说Thread运行是相对独立的,而service运行,它是依托于它所在的主线程上面,相比Thread,service并不是这么独立.
这是一点.Service是运行在主线程里面的,绝对不能做执行耗时操作,在这里强调一下,大家不能把后台和子线程联系在一起,这是两个完全不同的概念,服务和后台也是两个不同的概念,安卓的后台指的是,它的运行完全不依赖于UI线程,即使Activity被销毁了,程序被关闭了,服务进程仍然存在,它会在后台进行一些计算,进行一些数据统计。这时候service仍然可以继续运作。既然我们知道了service是不可以做耗时操作的,你如果一定要做耗时操作,在service里面,你也一定要创建子线程,然后在这里做耗时操作逻辑,既然在service里面也要创建一个子线程,那么为什么不直接在activity里面直接创建呢?因为activity很难以对子线程进行控制,特别是当activity被销毁的之后,你没有任何其它办法可以再获取之前创建的子线程实例,这是非常重要的一点。而service处理后台任务,activity就可以很放心的摧毁啊,finish掉,完全不用担心,无法对后台进行控制情况。
总结一下service和Thread之间的区别:
首先第一点,定义上,thread是程序执行的最小单元,他是分配cpu的基本单位,安卓系统中,我们常说的主线程,UI线程,也是线程的一种,当然,线程里面还可以执行一些耗时的异步操作。而service大家记住,它是安卓中的一种特殊机制,service是运行在主线程当中的,所以说它不能做耗时操作,它是由系统进程托管,其实service也是一种轻量级的IPC通信,因为activity可以和service绑定,可以和service进行数据通信,而且又一种情况,activity和service是处于不同的进程当中,所以说它们之间的数据通信,要通过IPC进程间通信的机制来进行操作。
第二点是在实际开发的过程当中,在安卓系统当中,线程一般指的是工作线程,就是后台线程,做一些耗时操作的线程,而主线程是一种特殊的线程,它只是负责处理一些UI线程的绘制,UI线程里面绝对不能做耗时操作,这里是最基本最重要的一点。(这是Thread在实际开发过程当中的应用)而service是安卓当中,四大组件之一,一般情况下也是运行在主线程当中,因此service也是不可以做耗时操作的,否则系统会报ANR异常(ANR全称:Application Not Responding),就是程序无法做出响应。如果一定要在service里面进行耗时操作,一定要记得开启单独的线程去做。
第三点,应用场景上,当你需要执行耗时的网络,或者这种文件数据的查询,以及其它阻塞UI线程的时候,都应该使用工作线程,也就是开启一个子线程的方式,这样才能保证UI线程不被占用,而影响用户体验。而service来说,我们经常需要长时间在后台运行,而且不需要进行交互的情况下才会使用到服务,比如说,我们在后台播放音乐,开启天气预报的统计,还有一些数据的统计等等。
二、开启service的两种方式以及区别
1.startservice
你通过Activity调用startservice启动服务的时候,这个服务就一直处于启动状态,而一旦,这个服务开启启动,这个服务就会在后台无限期的运行,这时候如果你的activity被销毁了,也对它的service运行不受影响,除非你手动的去关闭这个service,这样service才会停止.
1.定义一个类继承Service
2.在Manifest.XML文件中配置该Service
3.使用Context的startService(Intent)方法启动该Service
4.不再使用时,调用stopService(Intent)方法停止该服务
2.bindService
你绑定服务的时候,服务和activity已经处于绑定状态了,绑定服务,他提供了一个客户端和一个服务端的接口,相当于Activity和service进行交互的接口,它允许客户端和service进行数据交互啊,发送请求获取结果等等,甚至如果service,activity在不同进程当中的 时候,可以进行进程间的通信,来传输数据,这仅仅要在service绑定到Activity之后才能运行,同时你多个Activity可以绑定一个service,但是,如果全部取消之后,这个服务会自动被销毁,它并不一定像startservice里面一样,调用stopservice才能被销毁.
我们来看一下启动方式:
1.创建BindService服务端,继承自Service并在类中,创建一个实现IBinder接口的实例对象并提供公共方法给客户端回调
2.从onBind()回调方法返回此Binder实例.
3.在客户端中,从onServiceConnected()回调方法接收Binder,并使用提供的方法调用绑定服务.(注:客户端指的是Activity,服务端指的是service)