Service是Android四大组件之一,与Activity的职责相反,Service一般在后台处理一些耗时任务,或者一直执行某个任务。

Service使用

新建一个计时Service。

public class TimerService extends Service {private static String TAG = TimerService.class.getName();private static final long LOOP_TIME = 1; //循环时间private static ScheduledExecutorService mExecutorService;@Overridepublic void onCreate() {super.onCreate();Log.d(TAG, "onCreate");mExecutorService = Executors.newScheduledThreadPool(2);mExecutorService.scheduleAtFixedRate(mRunnable, LOOP_TIME, LOOP_TIME, TimeUnit.SECONDS);}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.d(TAG, "onStartCommand");return super.onStartCommand(intent, flags, startId);}@Nullable@Overridepublic IBinder onBind(Intent intent) {Log.d(TAG, "onBind");return null;}@Overridepublic void onDestroy() {Log.d(TAG, "onDestroy");super.onDestroy();mExecutorService.shutdown();mExecutorService = null;mRunnable = null;}private int count = 0;private Runnable mRunnable = new Runnable() {@Overridepublic void run() {count++;Log.d(TAG, "=== count:" + count);}};
}

四大组件都需要在manifest中注册

   <service android:name=".service.TimerService"/>

声明Service的时候还有一些属性可以一起配置。需要的话

  <service android:name=".service.TimerService"android:enabled="true"android:exported="true"android:icon="@mipmap/ic_launcher"android:label="string"android:process="string"android:permission="string"><!--设置service优先级,最大1000--><intent-filter android:priority="100"/></service>
  • android:enabled 是否允许除了当前程序之外的其他程序访问这个服务

  • android:exported 是否启用这个服务

  • android:process 是否需要在单独的进程中运行,当设置为android:process=”:remote”时,代表Service在单独的进程中运行。注意“:”很重要,它的意思是指要在当前进程名称前面附加上当前的包名,所以“remote”和”:remote”不是同一个意思,前者的进程名称为:remote,而后者的进程名称为:App-packageName:remote。

  • android:permission 权限声明

我们知道Service的使用方式有两种,我们分别使用不同的方式进行使用。

1、使用startService()方法启动服务

  Intent intent = new Intent(ServiceActivity.this, TimerService.class);//使用Intent传值intent.putExtra("key","value");startService(intent);

启动任务,查看控制台我们输出的Log

TimerService: onCreate
TimerService: onStartCommand
TimerService: === count:1
TimerService: === count:2
......

可以看见,Service被创建,并且计时任务在后台执行。

如果我们不小心多点了次启动按钮,会发生什么事呢?会有两个计时任务一起执行么?我们将APP卸载重新运行可以试着多点几次启动,查看控制台输出日志:

TimerService: onCreate
TimerService: onStartCommand
TimerService: === count:1
TimerService: onStartCommand
TimerService: onStartCommand
TimerService: onStartCommand
TimerService: === count:2
......

从日志上可以看见,我们连续点击启动按钮启动服务,服务并不会重新创建 ,而是执行onStartCommand方法,因为我们计时任务的初始化和启动都是放在onCreate方法中的,所以不会启动多个计时任务。

停止服务
服务一旦启动,除非我们手动关闭服务,否则服务会一直在后台运行,直到系统资源不足的时候,系统主动杀死服务。

使用stopService停止服务。

stopService(new Intent(ServiceActivity.this, TimerService.class));

控制台输出如下:

TimerService: onDestroy

所以使用startService方式启动服务的service生命周期为:

oncreate --> onStartCommand --> onDestroy

  • onCreate:服务创建的时候调用一次,如果已经创建了,则不会再调用。
  • onStartCommand : 当通过startService() 启动服务时,系统将调用此方法。一旦执行此方法,服务即会启动并可在后台无限期运行。
  • onDestroy:当服务不再使用且将被销毁时,系统将调用此方法。

多次启动服务会重复执行onStartCommand 方法。

2、使用bindService 绑定服务

bindService和startService的最大区别是,客户和服务绑定在一起了,客户可以通过binder获得Service实例,从而达到交互的目的。

bindService()方法有三个参数。Intent,ServiceConnection,flags

创建Intent和ServiceConnection

 private ServiceConnection mServiceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder iBinder) {Log.d("tag", "onServiceConnected");}@Overridepublic void onServiceDisconnected(ComponentName name) {Log.d("tag", "onServiceDisconnected");}};

通过绑定服务启动服务和unbindService解绑服务

   Intent intent = new Intent(ServiceActivity.this, TimerService.class);//BIND_AUTO_CREATE 自动创建Service。bindService(intent, mServiceConnection, BIND_AUTO_CREATE);

运行结果如下:

TimerService: onCreate
TimerService: onBind
   //解除绑定unbindService(mServiceConnection);

运行结果如下:

TimerService: onCreate
TimerService: onBind
TimerService: onUnbind
TimerService: onDestroy

可以看出通过bindService方式启动服务,完整生命周期方法为:
onCreate() --> onBind() --> onUnbind -->onDestroy()

此时我们的onBind方法返回的还是一个空的IBinder。

    @Nullable@Overridepublic IBinder onBind(Intent intent) {Log.d(TAG, "onBind");return null;}

创建一个IBinder实例,返回此TimerService。

    public class MyBinder extends Binder{TimerService getService(){return TimerService.this;}}

修改onBind返回值。在 onServiceConnected(ComponentName name, IBinder iBinder)方法中通过IBinder 获得

    private MyBinder mMyBinder = new MyBinder();@Nullable@Overridepublic IBinder onBind(Intent intent) {Log.d(TAG, "onBind");return mMyBinder;}

修改mServiceConnection,onServiceConnected方法中的IBinder对象就是上面onBinder()方法中返回的对象

    private TimerService timerService;private ServiceConnection mServiceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder iBinder) {TimerService.MyBinder myBinder = (TimerService.MyBinder) iBinder;timerService = myBinder.getService();mCounterTv.setText(timerService.getCount() + "");Log.d("tag", "onServiceConnected");}@Overridepublic void onServiceDisconnected(ComponentName name) {Log.d("tag", "onServiceDisconnected");}};

再次执行bindService();运行结果如下

TimerService: onCreate
TimerService: onBind
D/tag: onServiceConnected

可以看出当service中的onBind()方法返回一个不为空的IBinder对象时,onServiceConnected方法被执行,表示activity和service已经成功连接。我们也已经通过IBinder 成功获得TimerService对象实例,从而对service进行操作。

通过两种启动方式启动同一个Service

当我们通过两种方式启动同一个service,此时service的生命周期如何?

TimerService: onCreate
TimerService: onStartCommand
TimerService: onBindD/ServiceActivity: onServiceConnected
TimerService: === count:1D/ServiceActivity: 调用了stopService()
TimerService: === count:2
TimerService: === count:3D/ServiceActivity: 调用了unbindService()
TimerService: onUnbind
TimerService: onDestroy

可以看到,当使用两种方式启动同一个服务时,只用一种方式是取消不了服务的,要同时调用stop和unbind方法才行。

Android Service使用相关推荐

  1. Android Service

    Android Service 和BroadCast .Activity.以及ContentProvider并称为安卓四大组件.在日常开发中接触最多的是Activity,因为android其实就是一个 ...

  2. android 浏览器源码分析,从源码出发深入理解 Android Service

    原标题:从源码出发深入理解 Android Service 原文链接: 建议在浏览器上打开,删除了大量代码细节,:) 本文是 Android 系统学习系列文章中的第三章节的内容,介绍了 Android ...

  3. android service 学习(上)

    转载自:http://www.cnblogs.com/allin/archive/2010/05/15/1736458.html Service是android 系统中的一种组件,它跟Activity ...

  4. android service 学习(下)

    android service 学习(下) 通常每个应用程序都在它自己的进程内运行,但有时需要在进程间传递对象,你可以通过应用程序UI的方式写个运行在一个不同的进程中的service.在android ...

  5. android service是单例么,android 使用单例还是service?

    stackover看到的回答,挺不错的. I'm quite new to Android development. When is it a good idea to create an Andro ...

  6. Android Service的思考(1)

    在Android框架中,Service是比较难以理解的一部分,傻蛋查阅了相关资料和经过一系列的代码测试,准备写一个系列文章,尝试着把Service由浅入深的梳理一遍,帮助大家更快的掌握Android ...

  7. Android Service 服务(二)—— BroadcastReceiver

    一. BroadcastReceiver简介 BroadcastReceiver,用于异步接收广播Intent,广播Intent是通过调用Context.sendBroadcast()发送.Broad ...

  8. Android Service完全解析,关于服务你所需知道的一切(下)

    转载请注册出处:http://blog.csdn.net/guolin_blog/article/details/9797169 在上一篇文章中,我们学习了Android Service相关的许多重要 ...

  9. Android Service使用方法--简单音乐播放实例

    Service翻译成中文是服务,熟悉Windows 系统的同学一定很熟悉了.Android里的Service跟Windows里的Service功能差不多,就是一个不可见的进程在后台执行. Androi ...

  10. Android Service的onStartCommand返回值用法

    2019独角兽企业重金招聘Python工程师标准>>> Android Service的onStartCommand返回值用法 本文目的:使读者快速理解 1.START_STICKY ...

最新文章

  1. iMeta:德布鲁因图在微生物组研究中的应用(全文翻译,PPT,视频)
  2. php显示类别名,如何在single.php中仅显示父类别名称? (wordpress)
  3. Madagascar和MPI混合编程的Makefile文件配置
  4. sql server 锁与事务拨云见日(下)
  5. PHP清除HTML代码、空格、回车换行符的函数
  6. Windows程序员进阶应该看的那些书
  7. 181228每日一句
  8. timeout of 50000ms exceeded 原因及解决方案
  9. 计算机输出科学计数法,python不用科学计数法
  10. EasyCVR通过Ehome协议接入设备,获取RTSP流地址异常如何解决?
  11. Android开发环境配置(内有完整过程配图)
  12. 网络时间协议 (SNTP)
  13. 微信技术总监:一亿用户背后的架构秘密
  14. 苹果弃妇效应再现:Audience一夜跌去63%(转)
  15. mui12搭载鸿蒙,MUI系统最新资讯
  16. HTML 6种空格nbsp;ensp;emsp;thinsp;zwnj;zwj;空白空格的区别
  17. JAVA实现本月国际国内节日
  18. 新鲜出炉!由腾讯安全深度参编的“首份网络安全态势感知国家标准”发布
  19. 劳拉甘拜下风 看尖端科技如何挖古墓的
  20. 【免费】中国省级行政单位ISO 3166-2对照表

热门文章

  1. SAP S/4 HANA Cloud实施方法论
  2. Log抓取和分析-BugReport
  3. 【转】gcc for Windows 开发环境介绍
  4. 使用开发者工具等跳过付费墙
  5. APSIM练习:播种作物练—高粱作物模拟
  6. auto uninstaller 密钥 破解 修复卸载工具
  7. matlab RRR机械臂 简略代码
  8. 老男孩第十四期Python学习班之Day01
  9. 计蒜客T1249——漂亮的字符串
  10. I’ve Got Your Back(gammon)