int常量
用于标记某个任务
;Handler对象
,
同时重写Handler
的handleMessage()
方法,
方法中通过使用if
或者switch
,
将(子线程发送的)Message
的what
字段
同一个或者以上的int任务标志常量
做匹配,
调用对应的任务处理模块
进行处理;Thread、Runnable()、run()、start()
等类与方开启子线程,在子线程的线程任务执行单位(即run()
)中:
3.1. 实例化Message
对象;
3.2. 将任务常量id
设置到Message
实例对象的what
字段中;
3.3. 使用2.中定义的Handler
实例调用sendMessage()
将Message
实例发送到MQ
;
至此完成; onCreate()
:服务第一次被创建时调用
onStartComand()
:服务启动时调用
onBind()
:服务被绑定时调用
onUnBind()
:服务被解绑时调用
onDestroy()
:服务停止时调用
onBind()
方法,
有选择的重写onCreate()、onStartCommand()
及onDestroy()
方法;在配置文件中进行注册;
或者直接按照以下方法则AS会自动注册:
Intent intent = new Intent(this, MyService.class);// MyService是刚刚定义好的Service
startService(intent);
Service的停止:
Intent intent = new Intent(this, MyService.class);
stopService(intent);
类(如MyService)
继承自Service
并注册
好;内部类(如MyBinder)
继承Binder
,
在其内部编写要放在Service后台服务
执行的逻辑方法模块;继承自Service
的类(MyService)
中
实例化继承Binder的内部类(MyBinder)实例
并作为MyService
的成员变量;onBind()
方法,返回成员变量MyBinder实例
;启动Service
的活动
中,
在活动中实例化一个ServiceConnection类
对象,
并重写它的onServiceConnection()
和onServiceDisconnection()
方法,
这两个方法分别会在活动与服务
成功绑定
以及解除绑定
的时候调用。
在onServiceConnected()
方法中,
又通过向下转型得到了MyBinder
的实例,
有了它就可以在活动中
调用MyBinder中
的任何非private方法了
,
即实现Service与Activity的通信
。bindService()
实现绑定
,
它接收三个参数(Intent对象,ServiceConnection对象,标志位
),
这里传入BIND_AUTO_CREATE
表示在活动和服务进行绑定后自动创建服务
,unbindService(
)实现解绑
,
传入ServiceConnection
对象即可。
前台Service类似通知,
只不过在构建好一个Notification
之后,
不需要NotificationManager
将通知显示出来,
而是调用了startForeground()
方法。
可以在新建的继承Service
的类的onCreate()
方法中,如下编写:
启动方法同普通Service,即在对应的场景(如某个View的回调方法中)编写:
Intent intent = new Intent(this, MyService.class);// MyService是刚刚定义好的Service
startService(intent);
除了自定义一个Service
,可以使用现有的系统服务
;
通过getSyetemService()
方法并传入一个Name
即可得到相应的服务对象,
常用的系统服务如下表:
AlarmManager
系统服务,实现一个后台定时任务调用AlarmManager
的set()
方法就可以设置一个定时任务
,
set()
有三个参数(工作类型,定时任务触发的时间,PendingIntent对象)
:
1)工作类型
:有四个值
可选:
2)定时任务触发的时间
:以毫秒
为单位,传入值
和第一个参数
对应关系:
3)PendingIntent对象
:
一般会调用它的getBroadcast()
方法来获取一个能够执行广播的PendingIntent
。
这样当定时任务被触发的时候,
广播接收器中的onReceive()
方法即可得到执行,
在onReceive()
方法我们可以再次启动Service
,
同时编写任务执行代码块;
实战使用时,
可以在新建的继承Service
的类的onStartCommand()
方法中,
如下编写:
注意这里的提供给PendingIntent
的Intent
跳转到的广播接收器
是需要我们自己定义的
,
这里定义的接收器是MyBroadcast
:
如此一来,
一旦启动MyService
,
就会在onStartCommand()
方法里设定一个定时任务
,
10秒
后MyReceiver
的onReceive()
方法将被回调执行,
紧接着又反过来启动MyService
,反复循环。
从而实现一个能长期在后台进行定时任务的服务。
同时在MyReceiver
的onReceive()
方法中
我们可以添加编写任务执行代码块
;
另外,从
Android 4.4
版本开始, 由于系统在耗电性方面进行了优化使得Alarm任务的触发时间会变得不准确。 如果一定要求Alarm任务的执行时间精确, 把AlarmManager
的setExact()
方法替代set()
方法就可以了。
使用Android提供的IntentService,
可以简单地实现一个异步的、会自动停止的服务;
IntentService
,
类中提供一个无参的构造函数
且必须在其内部
调用父类的有参构造函数
;
然后重写onHandleIntent()
方法,
里面可以处理一些耗时操作而不用担心 ANR的问题,
因为这个方法已经是在子线程中运行的了。Intent
启动IntentService
,同普通Service。实战参考:
onHandleIntent()
方法中为了证实这个方法确实已经在子线程中,
打印了当前线程的id
与稍后与主线程的线程id
作对比。
另外,IntentService的特性是在运行结束后应该是会自动停止
,
这里重写onDestroy()
方法在其中打印一行日志,
证实服务是不是停止掉
了。
接着注册:
或者直接按照以下方法则AS会自动注册:
在对应的场景(如某个View的回调方法中),
利用Intent可实现Service的启动,同普通Service:
在这里打印了主线程的 id
,
用于同方才说的IntentService
中
onHandleIntent()
方法中打印的线程id
进行对比;