专栏名称: 安卓开发精选
伯乐在线旗下账号,分享安卓应用相关内容,包括:安卓应用开发、设计和动态等。
目录
相关文章推荐
开发者全社区  ·  金融本科就业无望,商转男模未来可期 ·  13 小时前  
开发者全社区  ·  真男人的觉醒 ·  18 小时前  
鸿洋  ·  Android×AI×鸿蒙生态周刊#2|跨端 ... ·  昨天  
开发者全社区  ·  97岁李嘉诚 ·  2 天前  
开发者全社区  ·  字节跳动出手:直接辞退353人! ·  3 天前  
51好读  ›  专栏  ›  安卓开发精选

Android 组件 Service 研究

安卓开发精选  · 公众号  · android  · 2016-08-27 08:16

正文

(点击 上方公众号 ,可快速关注)


来源:伯乐在线专栏作者 - dreamist

链接:http://android.jobbole.com/84450/

点击 → 了解如何加入专栏作者


Service组件概述


Service是android系统的主要组件之一,就像Activity一样,对于开发者来说几乎是必须掌握的。Service的职责是进行一些不需要UI存在操作的,比如网络请求、本地磁盘IO、之行定时任务等。Service是没有图形界面的,只会在后台默默地运行。


注意:Service只是在后台运行的一个组件,默认情况下,Service也是运行在app的主线程中的,它并不会开启新的线程或者进程(当然,这个可以做到)。所以,假如在Service中执行有耗时的操作的话,最好让Service运行在新的线程或者进程里面。


Service 与 线程


在android中,Service只是一个组件,用于满足一些特定的场景而设计的一个常用组件,和线程并不是一回事。如上所述,默认情况下,Service也是运行在app的主线程中的,就像其它组件一样。如果需要在Service中做耗时的或者阻塞的操作的话,最好在Service中开启子线程处理。Service更像是一个独立的服务,一个Service除了被自身的app组件所用外,还可以被其它的app调用(可以通过在 android:exported属性中设置是否允许其它app使用自己的Service),当然,可以是跨进城的调用。所以,在使用的时候不要把Service 和 线程混淆了。


Service 的两种启动形式


  • Started形式(可启动)。该类Service需要实现onStartCommand()方法。由一个其它的android组件来启动一个Service,可以调用startService()方法来实现。这种形式的Service的特点是,一旦Service启动完成后,该Service便会在后台独立地运行,不再受启动它的组件的生命周期的影响。通常来说,该类Service再被启动后做一些不用给启动者返回值的操作,因为该类Service的生命周期要比启动它的组件的要长,所以假如该类Service返回结果的话,无法确定它的启动者是否还活着。举例来说,该类Service就像是扫地机器人,主人把它打开后它就会负责再家中打扫卫生,不管主人是不是还在家,它也不需要报告主人打扫的怎么样了。当该类Service的工作完成后,它应该自己停止自己。当然,其它组件也可以在Service运行的时候选择停止它。

  • Bound形式(可绑定)。该类Service需要实现onBind()方法。一个android组件通过调用bindService()方法来启动一个Service,这个时候该启动者组件会与Service实例形成一个Client-Service结构。Service会提供服务端的接口以便Client端和它进行交互。调用者可以给该类Service发请求,获取结果,委派其完成任务等。该类Service只有在其它组件和其绑定的时候才会启动,而且允许多个不同的组件和它进行绑定。当一个该类的Service没有在运行的和其绑定的组件的时候,该Service实例就会被销毁。


以上两种形式的Service也可以同时使用,只要把onStartCommand() 和 onBind()两个方法同时实现就可以了。这样的话,得到的Service将会具有以上两者的特性。


问题思考:同一个Service的类在android中可以有多个实例吗?


答:不可以。Service的启动模式决定它不会在系统中存在多个实例,当有新的Intent传递过来的时候,android系统会直接使用已经存在的Service实例而不会重新创建,所以在android系统中的Service都是单例的。


Service 生命周期管理


android官方提供了Service的生命周期图:



开发者在开发的时候,要注意的是Service一旦用过之后一定要注意stop掉Service,如果是bind的Service一定要手动调用unBind方法,这样不光是从自己的Service的安全性考虑,而且这样会更加节省系统资源和电量消耗。


IntentService


简介


IntentService 是Service的一个子类,属于上述的可启动的类型的Service。是官方封装的一个易于使用的Service,它的特点是同步地接受多个start请求,一个接一个地处理它们。并且IntentService里面处理start请求的是在一个独立的线程里进行的,所以可以用来执行耗时的操作而不影响主线程中UI的绘制。使用的时候只需要实现onHandleIntent()方法来接收其它组件传递过来的Intent对象就可以了。IntentService可以满足平常开发中大部分需要使用Service的场景了。


IntentService详情


IntentService做的具体工作由以下这些


  • 创建一个子线程,在子线程里面把Intent实例分发到onStartCommand()方法

  • 创建一个队列,一个接一个地把Intent实例传递到onHandleIntent()方法里面,所以使用的时候不需要担心多线程同步的问题,因为IntentService发送Intent本身就是同步的。

  • 在处理完所有的start请求之后,IntentService会自动停止,所以使用者不用主动去停止。

  • 提供一个对onBind()方法的实现,返回null

  • 提供一个对onStartCommand()方法的实现,并且在里面实现Intent实例发送到上述的Intent处理队列中。


注意:在继承IntentService之后,如果重写了Service生命周期的回调方法,像onCreate,onStartCommand,onDestroy()等,应该在其中调用super方法来保证IntentService能正确的被使用(但是onBind方法中不必要调用spuer,因为如上所述,IntentService中默认的onBind实现是一个返回null的操作,并没有做什么具体的工作)。例如:


> @Override

> public int onStartCommand ( Intent > intent , int flags , int startId ) {

> Toast . makeText ( this , "service >starting" , > Toast . LENGTH_SHORT ). show ();

> return > super . onStartCommand ( intent ,







请到「今天看啥」查看全文


推荐文章
开发者全社区  ·  金融本科就业无望,商转男模未来可期
13 小时前
开发者全社区  ·  真男人的觉醒
18 小时前
开发者全社区  ·  97岁李嘉诚
2 天前
开发者全社区  ·  字节跳动出手:直接辞退353人!
3 天前
半导体行业观察  ·  苹果将公司的未来押在Siri上
8 年前