按照上图创建ServiceAbility,会自动生成带有生命周期的类和配置文件:
package com.example.serviceabilitydemo;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.rpc.IRemoteObject;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
public class ServiceAbility extends Ability {
private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "Demo");
@Override
public void onStart(Intent intent) {
HiLog.error(LABEL_LOG, "ServiceAbility::onStart");
super.onStart(intent);
}
@Override
public void onBackground() {
super.onBackground();
HiLog.info(LABEL_LOG, "ServiceAbility::onBackground");
}
@Override
public void onStop() {
super.onStop();
HiLog.info(LABEL_LOG, "ServiceAbility::onStop");
}
@Override
public void onCommand(Intent intent, boolean restart, int startId) {
}
@Override
public IRemoteObject onConnect(Intent intent) {
return null;
}
@Override
public void onDisconnect(Intent intent) {
}
}
{
"name": "com.example.serviceabilitydemo.ServiceAbility",
"icon": "$media:icon",
"description": "$string:serviceability_description",
"type": "service",
"visible": true
}
启动ServiceAbility跟跳转PageAbility的代码一模一样:
btnStartAbility.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.example.serviceabilitydemo")
.withAbilityName("com.example.serviceabilitydemo.ServiceAbility")
.build();
intent.setOperation(operation);
startAbility(intent);
}
});
从启动到结束的生命周期:
12-28 21:49:00.645 3798-3798/com.example.serviceabilitydemo E 01100/MyLog: ServiceAbility::onStart
12-28 21:49:00.646 3798-3798/com.example.serviceabilitydemo E 01100/MyLog: ServiceAbility::onCommand
12-28 21:49:13.521 3800-3800/? E 01100/MyLog: ServiceAbility::onStart
12-28 21:49:13.524 3800-3800/? E 01100/MyLog: ServiceAbility::onBackground
12-28 21:49:13.524 3800-3800/com.example.serviceabilitydemo E 01100/MyLog: ServiceAbility::onStop
onStart方法居然执行了两次,官方文档是这样的
由于我是用杀进程的方式停止Service的,于是我又试了试用stopAbility来停止Service:
Button btnStartAbility= (Button) findComponentById(ResourceTable.Id_btn_start_service);
if (btnStartAbility != null) {
// 为按钮设置点击回调
btnStartAbility.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.example.serviceabilitydemo")
.withAbilityName("com.example.serviceabilitydemo.ServiceAbility")
.build();
intent.setOperation(operation);
startAbility(intent);
}
});
}
Button btnStopAbility= (Button) findComponentById(ResourceTable.Id_btn_stop_service);
if (btnStopAbility != null) {
// 为按钮设置点击回调
btnStopAbility.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.example.serviceabilitydemo")
.withAbilityName("com.example.serviceabilitydemo.ServiceAbility")
.build();
intent.setOperation(operation);
stopAbility(intent);
}
});
}
这次是正常的:
12-28 21:55:12.115 28321-28321/com.example.serviceabilitydemo E 01100/MyLog: ServiceAbility::onStart
12-28 21:55:12.116 28321-28321/com.example.serviceabilitydemo E 01100/MyLog: ServiceAbility::onCommand
12-28 21:55:18.776 28321-28321/com.example.serviceabilitydemo E 01100/MyLog: ServiceAbility::onBackground
12-28 21:55:18.776 28321-28321/com.example.serviceabilitydemo E 01100/MyLog: ServiceAbility::onStop
不知道为什么杀进程会多执行一次onStart方法。
最后,连接ServiceAbility,先定义一个用来传递的类,这个类必须继承LocalRemoteObject:
package com.example.serviceabilitydemo;
import ohos.aafwk.ability.LocalRemoteObject;
public class MyRemoteObject extends LocalRemoteObject {
private String msg;
public MyRemoteObject() {
super();
}
public MyRemoteObject(String msg) {
super();
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
连接:
Button connStopAbility= (Button) findComponentById(ResourceTable.Id_btn_conn_service);
if (connStopAbility != null) {
// 为按钮设置点击回调
connStopAbility.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.example.serviceabilitydemo")
.withAbilityName("com.example.serviceabilitydemo.ServiceAbility")
.build();
intent.setOperation(operation);
// 连接Service
connectAbility(intent, connection);
}
});
}
其中connection是实现了IAbilityConnection接口的内部类
// 创建连接回调实例
private IAbilityConnection connection = new IAbilityConnection() {
// 连接到Service的回调
@Override
public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int resultCode) {
// Client侧需要定义与Service侧相同的IRemoteObject实现类。
// 开发者获取服务端传过来IRemoteObject对象,并从中解析出服务端传过来的信息。
MyRemoteObject remoteObject=(MyRemoteObject)iRemoteObject;
remoteObject.getMsg();
HiLog.error(LABEL_LOG, "onAbilityConnectDone() msg="+remoteObject.getMsg());
}
// 断开与连接的回调
@Override
public void onAbilityDisconnectDone(ElementName elementName, int resultCode) {
}
};
Service中要在onConnect方法返回数据:
@Override
public IRemoteObject onConnect(Intent intent) {
HiLog.error(LABEL_LOG, "ServiceAbility::onConnect");
return new MyRemoteObject("我是从服务器端返回的消息");
}
官方文档上还有这样一个流程:
但是我一旦执行连接ServiceAbility,就无法在执行停止ServiceAbility了,杀进程也不行。
Demo:https://download.csdn.net/download/y280903468/13973575