了解Ability中的ServiceAbility
简介
我们知道Ability是应用所具备的能力抽象,Ability又分为FA(Feature Ability)和PA(Particle Ability)两种类型,PageAbility就是FeatureAbility模板,用于提供应用与用户的交互功能,ParticleAbility又包含ServiceAbility和DataAbility两种类型,ServiceAbilit用于提供后台运行任务的能力,DataAbility用于对外部提供统一的数据访问能力。
简而言之,ServiceAbility也是一个Ability,那么创建就和我们创建PageAbility的方法差不多,但是在config.json里面注册的时候要将type设置成service就可以了。
Service的创建
通过File-new-Ability-Empty Service Ability的方法可以直接创建一个空的ServiceAbility
创建完成之后工具会自动帮我们在config.json里面注册该service,并且type设置成了service类型
{
"name": "com.example.demo1.LocalServiceAbility",
"icon": "$media:icon",
"description": "$string:serviceability_description",
"type": "service"
}
创建完成之后有以下几点需要注意:
- service是单例运行的,在通一个设备上,相同的service只能有一个。
- service可以允许多个业务Ability公用这个实例,当有多个业务公用这个service时,需要所有业务Ability都解绑之后才能停止该service。
- service是运行在主线程的,所以要执行数据库或者解析大文件等耗时操作的时候需要开启新的线程进行处理。
Service生命周期
先通过一张图来了解一下Servcice在被调用之后执行的步骤
Service创建步骤:
- 当有业务调用startAbility时,service会进入initial状态;
- 当Service从initial状态变成inactive非激活状态时会调用onStart()这个回调方法。
- 当Service从inactive状态变成active状态时会调用onCommond()这个回调方法。
- 当用户发出指令调用stopAbility停止Service时,Serivce会调用onBackGround()方法,这时Service的状态会从active变成background状态。
- 最后调用onStop()方法结束该Service。
回调方法:
- onStart() 该方法在创建Service的时候调用,用于Service的初始化。在Service的整个生命周期只会调用一次,调用时传入的Intent应为空。
- onCommand() 在Service创建完成之后调用,该方法在客户端每次启动该Service时都会调用,用户可以在该方法中做一些调用统计、初始化类的操作。
- onStop() 在Service销毁时调用。Service应通过实现此方法来清理任何资源,如关闭线程、注册的侦听器等。
Service从被业务调用startAbility开始就会在后台一直存在,不会自动关闭,只有当手机内存不够了,在回收一些长期不使用的资源的时候会回收,当然我们也可以通过stopAbility来停止service,然后系统将该service销毁。
本地Service的启动和停止
我们都知道Service是一个Ability,那么就可以使用Ability的启动方式进行启动,通过Intent这个意图包裹住Service的相关信息,就可以启动Service,这里有一点需要注意,启动Service是无法返回数据的,就比如A手机操作B手机的service进行媒体播放,那么只能控制播放和停止,无法返回具体的数据。
Service的启动
上面一直有说到Service也是一个Ability,那么我们启动Service的方法依然是通过Intent意图的方式进行启动:
Intent startService = new Intent();
Operation operation = new Intent.OperationBuilder()
.withBundleName("com.example.demo1")
.withAbilityName("com.example.demo1.LocalServiceAbility")
.build();
startService.setOperation(operation);
startAbility(startService);
将生命周期调用情况输出在控制台,这时候onStart方法会被调用:
Service的停止
通过stopAbility的方式停止Service,Intent的目标和开启的目标一样
Intent startService = new Intent();
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.example.demo1")
.withAbilityName("com.example.demo1.LocalServiceAbility")
.build();
startService.setOperation(operation);
stopAbility(startService);
onCommond方法参数含义
重写onCommond方法后我们可以看到有三个回调参数intent、restart、startId:
@Override
public void onCommand(Intent intent, boolean restart, int startId) {
}
参数含义:
- intent 启动service时传递的意图。
- restart 代表ability的启动方式,如果该值是true,代表service是被销毁后的重启,如果该值是false,代表是正常重启。
- startId 计数器,onCommond每被调用一次,该数值+1。
Service的连接和断开
Service的连接和Service的启动是不一样的,通过Service的连接可以让发起连接的业务PageAbility和ServiceAbility之间建立数据连接的桥梁,而启动Service是无法返回数据的。当我们要在Service里面执行逻辑操作,然后将操作结果返回时,就需要业务Ability与Service之间连接,而不能直接启动Service;总结就是从业务Ability启动Service,service和业务之间无法进行通信,而从业务Ability发起连接Service,Service可以和Ability进行通信。
Service连接的生命周期
- onConnect() 在Ability和Service连接时调用,该方法返回IRemoteObject对象,用户可以在该回调函数中生成对应Service的IPC通信通道,以便Ability与Service交互。Ability可以多次连接同一个Service,系统会缓存该Service的IPC通信对象,只有第一个客户端连接Service时,系统才会调用Service的onConnect方法来生成IRemoteObject对象,而后系统会将同一个RemoteObject对象传递至其他连接同一个Service的所有客户端,而无需再次调用onConnect方法。
- onDisconnect() 在Ability与绑定的Service断开连接时调用。
Service的连接
通过上面的操作我们知道启动一个Service使用的是startAbility,那么连接一个Service使用的就是connectAbility,通过源码我们可以看到需要我们传递两个参数,一个是Intent意图目标,一个是IAbilityConnection回调接口
public final boolean connectAbility(Intent intent, IAbilityConnection conn)
throws IllegalArgumentException, IllegalStateException {
throw new RuntimeException("Stub!");
}
那么我们就需要创建一个新的对象,实现该接口
private IAbilityConnection connection = new IAbilityConnection() {
@Override
public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int resultCode) {
}
@Override
public void onAbilityDisconnectDone(ElementName elementName, int resultCode) {
}
};
-
onAbilityConnectDone 与Service连接上后触发的回调
IRemoteObject 这个就是传递在业务Ability和Service之间通信的桥梁,开发者获取服务端传过来IRemoteObject对象,并从中解析出服务端传过来的信息。这个值会在Service的onConnect方法被调用的时候返回,所以Servce类内需要创建IRemoteObject实现类
// 创建自定义IRemoteObject实现类
private class MyRemoteObject extends LocalRemoteObject {
MyRemoteObject(){
}
}
// 把IRemoteObject返回给客户端
@Override
protected IRemoteObject onConnect(Intent intent) {
return new MyRemoteObject();
}
- onAbilityDisconnectDone 与Service连接断开后触发的回调
连接代码
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.example.demo1")
.withAbilityName("com.example.demo1.LocalServiceAbility")
.build();
intent.setOperation(operation);
connectAbility(intent, connection);
Service的断开
通过disconnectAbility()方法断开Service连接,传入对应的IAbilityConnection
public final void disconnectAbility(IAbilityConnection conn) throws IllegalArgumentException, IllegalStateException {
throw new RuntimeException("Stub!");
}
调用代码
disconnectAbility(connection);
以上就是Service的基本操作了。