Android四大控件之Service的初学
什么是服务呢?
用俗话话应该是长期于后台运行的程序,如果是官方一点,首先它是一个组件,用于执行长期运行的任务,并且与用户没有交互。
创建一个服务和活动类似,都需要在Android.xml文件中设置service标签
因为服务也存活于进程之中,所以这里来介绍一下优先级由大到小的顺序
1、前台进程:可以理解为是最顶部的,直接跟用户交互的。比如说我们操作的Activity界面.
2、可见进程:可以见的,但是不操作的,比如说我们在一个Activity的顶部弹出一个Dialog,这个Dialog就是前台进程,但是这个Activity则是可见进程。
3、服务进程:服务可以理解为是忙碌的后台进程,虽然是在后台,但是它很忙碌。
4、后台进程:后台进程就是退隐到后台,不做事的进程。
5、空进程:空进程是不做事的,没有任何东西在上面跑着,仅作缓存作用。
假设,内存不够用了,会先杀谁呢?
首先杀的是空进程,要是还不够就杀后台进程,要是还不够,那么就杀服务,但是服务被杀死以后,等内存够用了,服务又会跑起来了。
我们先创建一个服务类,继承自service,有两种启动服务的方式
第一种方式为:
public void openFirstService(View view) { intent = new Intent(this, MyFirstService.class); startService(intent); } public void closeFirstService(View view) { stopService(intent); }
service类里面我们重写生命周期的方法,onStart()方法已经弃用,打印日志信息如下:
如果直接在活动页面创建一个服务类对象,再调用里面的方法,这样会报错,因为服务存在于后台。
Service和Activity都是Context上下文的子类。
接下来是第二种绑定服务的方法
既然传统的start启动服务,不能实现活动和服务的交互,那么自然就迎来第二种,绑定的方式。
我们在创建服务类时,会强制让我们重写onBind方法,返回的类型是IBinder,翻译过来就是粘合剂,把服务和活动粘合起来
这里我们可以采取创建内部类的形式,继承自Binder(ps:Ibinder是接口,Binder是实现接口的类)
我们在内部类里面写好向外提供的方法,然后再进一步调用服务自己的方法。这里onBind的返回值也就是我们的粘合剂对象了。
接着再返回到我们的活动页面
这里还是老样子创建一个意图对象,设置服务的映射(Service.class)
接着方法变成了bindService()里面有三个参数,第一个参数是一个Intent对象,第二个参数是ServiceConnection的实现类对象,这里我们采用的是匿名内部类的方式用来重写里面的方法
第三个参数BIND_AUTO_CREATE是一个常量,代表自动匹配进行绑定,如果发现活动页面已经存在服务,就不会再绑定了
接着绑定完服务之后,通过Connction对象获取到粘合剂对象,就可以调用粘合剂里面的方法来实现和服务的交互了。
以下是绑定服务和开启服务的区别,节选自电锯程序员
1、绑定服务在系统设置里是没有显进服务正在跑着的;
2、如果onBind方法返回的是null,那么onServiceConnected方法不会被调用;
3、绑定服务的生命周期跟Activity是不求同时生,但求同时死,Activity没了,服务也要解绑;
4、服务在解除绑定以后会停止运行,执行unBind方法—>onDestroy方法;
5、绑定服务开启的服务,只可以解绑一次,多次解绑会抛异常;
6、绑定的connection要跟解绑的connection要对应着,否则没法解绑。
稍微总结一下,startService和bindService的区别,优点和缺点:
1、startService这个方法来启动服务的话,是长期运行的,只有stopService才会停止服务。而bindService来启动服务,不用的时候,需要调用unBindService,否则会导致context泄漏,所以bindService不是长期运行的。当context销毁的时候,则会停止服务运行。
2、startService来启动服务可以长期运行,但是不可以通讯,而bindService的方式来启动服务则可以通讯,两者都有优缺点,所以我们就有了混合起来使用的方法。
其次电锯老师讲了一个接口的作用
当我们服务里面的粘合剂类不想让外界new的时候,我们可以设置为私有,但是这样的话外界的ServiceConnection类就不能获取到粘合剂类对象再赋值给活动的全局变量了。
这样的话,我们可以暴露一个接口,然后让粘合剂对象实现接口里面的方法,然后再把方法传给活动的全局变量。具体如图所示:
这样做的好处是,当书写活动界面的程序员,只需要写一个接口就行,不用管具体是如何实现的。
而负责实现服务类的程序员,根据接口的抽象方法,重写实现类就可以,这样可以提高并发的工作效率,也算是接口的一个作用吧。