前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Tip | Android的Service相关知识提炼

Tip | Android的Service相关知识提炼

作者头像
凌川江雪
发布2019-07-03 17:06:17
6160
发布2019-07-03 17:06:17
举报
文章被收录于专栏:李蔚蓬的专栏李蔚蓬的专栏

异步消息处理基本用法

  1. 准备int常量用于标记某个任务
  2. 主线程实例化Handler对象, 同时重写HandlerhandleMessage()方法, 方法中通过使用if或者switch, 将(子线程发送的)Messagewhat字段 同一个或者以上的int任务标志常量做匹配, 调用对应的任务处理模块进行处理;
  3. 在对应的场景(如某个View的回调方法中): 利用匿名类的方式,通过Thread、Runnable()、run()、start()等类与方开启子线程,在子线程的线程任务执行单位(即run())中:  3.1. 实例化Message对象;  3.2. 将任务常量id设置到Message实例对象的what字段中;  3.3. 使用2.中定义的Handler实例调用sendMessage()Message实例发送到MQ; 至此完成;

Service生命周期

onCreate():服务第一次被创建时调用

onStartComand():服务启动时调用

onBind():服务被绑定时调用

onUnBind():服务被解绑时调用

onDestroy():服务停止时调用

普通Service(开启Service的两个基本方法,其一)

  1. 新建一个类并令其继承Service且必须重写onBind()方法, 有选择的重写onCreate()、onStartCommand()onDestroy()方法;

在配置文件中进行注册;

或者直接按照以下方法则AS会自动注册:

  1. 在对应的场景(如某个View的回调方法中), 利用Intent可实现Service的启动:
代码语言:javascript
复制
 Intent intent = new Intent(this, MyService.class);// MyService是刚刚定义好的Service
 startService(intent);

Service的停止:

代码语言:javascript
复制
Intent intent = new Intent(this, MyService.class);
stopService(intent);

Service与Activity的通信(开启Service的两个基本方法,其二)

  1. 新建一个类(如MyService)继承自Service注册好;
  2. 类中定义一个内部类(如MyBinder)继承Binder, 在其内部编写要放在Service后台服务执行的逻辑方法模块;
  3. 继承自Service类(MyService)中 实例化继承Binder的内部类(MyBinder)实例 并作为MyService的成员变量;
  4. 重写onBind()方法,返回成员变量MyBinder实例
  5. 在对应启动Service活动中, 在活动中实例化一个ServiceConnection类对象, 并重写它的onServiceConnection()onServiceDisconnection()方法, 这两个方法分别会在活动与服务 成功绑定以及解除绑定的时候调用。 在onServiceConnected()方法中, 又通过向下转型得到了MyBinder的实例, 有了它就可以在活动中调用MyBinder中的任何非private方法了, 即实现Service与Activity的通信
  6. 最后在在对应的场景(如某个View的回调方法中), 利用Intent对象以及下面两个方法 实现活动和服务的绑定和解绑:
  7. bindService()实现绑定, 它接收三个参数(Intent对象,ServiceConnection对象,标志位), 这里传入BIND_AUTO_CREATE 表示在活动和服务进行绑定后自动创建服务
  8. unbindService()实现解绑, 传入ServiceConnection对象即可。

前台Service

前台Service类似通知,

只不过在构建好一个Notification之后,

不需要NotificationManager将通知显示出来,

而是调用了startForeground()方法。

可以在新建的继承Service的类的onCreate()方法中,如下编写:

启动方法同普通Service,即在对应的场景(如某个View的回调方法中)编写:

代码语言:javascript
复制
 Intent intent = new Intent(this, MyService.class);// MyService是刚刚定义好的Service
 startService(intent);

系统Service

除了自定义一个Service,可以使用现有的系统服务

通过getSyetemService()方法并传入一个Name

即可得到相应的服务对象,

常用的系统服务如下表:

下面学习AlarmManager系统服务,实现一个后台定时任务

调用AlarmManagerset()方法就可以设置一个定时任务

set()三个参数(工作类型,定时任务触发的时间,PendingIntent对象)

1)工作类型:有四个值可选:

2)定时任务触发的时间:以毫秒为单位,传入值第一个参数对应关系:

3)PendingIntent对象

一般会调用它的getBroadcast()方法来获取一个能够执行广播的PendingIntent

这样当定时任务被触发的时候,

广播接收器中的onReceive()方法即可得到执行,

onReceive()方法我们可以再次启动Service

同时编写任务执行代码块;

实战使用时,

可以在新建的继承Service的类的onStartCommand()方法中,

如下编写:

注意这里的提供给PendingIntentIntent

跳转到的广播接收器是需要我们自己定义的

这里定义的接收器是MyBroadcast

如此一来,

一旦启动MyService

就会在onStartCommand()方法里设定一个定时任务

10秒MyReceiveronReceive()方法将被回调执行,

紧接着又反过来启动MyService,反复循环。

从而实现一个能长期在后台进行定时任务的服务

同时在MyReceiveronReceive()方法中

我们可以添加编写任务执行代码块

另外,从Android 4.4版本开始, 由于系统在耗电性方面进行了优化使得Alarm任务的触发时间会变得不准确。 如果一定要求Alarm任务的执行时间精确, 把AlarmManagersetExact()方法替代set()方法就可以了。

IntentService

使用Android提供的IntentService,

可以简单地实现一个异步的、会自动停止的服务;

  1. 新建类并继承IntentService, 类中提供一个无参的构造函数 且必须在其内部调用父类的有参构造函数; 然后重写onHandleIntent()方法, 里面可以处理一些耗时操作而不用担心 ANR的问题, 因为这个方法已经是在子线程中运行的了。
  2. 在配置文件中进行注册。
  3. 在活动中利用Intent启动IntentService,同普通Service

实战参考:

onHandleIntent()方法中为了证实这个方法确实已经在子线程中,

打印了当前线程的id与稍后与主线程的线程id作对比。

另外,IntentService的特性是在运行结束后应该是会自动停止

这里重写onDestroy()方法在其中打印一行日志,

证实服务是不是停止掉了。

接着注册:

或者直接按照以下方法则AS会自动注册:

在对应的场景(如某个View的回调方法中),

利用Intent可实现Service的启动,同普通Service

在这里打印了主线程的 id

用于同方才说的IntentService

onHandleIntent()方法中打印的线程id进行对比;


参考学习笔记| AS入门(十) 组件篇之Service

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.07.02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 异步消息处理基本用法
  • Service生命周期
  • 普通Service(开启Service的两个基本方法,其一)
  • Service与Activity的通信(开启Service的两个基本方法,其二)
  • 前台Service
  • 系统Service
  • IntentService
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档