harmony ability
Ability(能力)是鸿蒙软件的基础单位,一个应用可以包含多个Ability。鸿蒙支持应用以Ability为单位进行部署
Page Ability
Page提供页面管理和页面跳转的能力。例如外卖提供联系商家的业务入口,当用户使用此功能时,会跳转到通话应用的拨号页面。鸿蒙支持Page之间的跳转,并且指定跳转到某个AbilitySlice
创建
右键就可以进行创建,并且它的配置文件如下{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [//路由名称
"action.system.home"
]
}
],
"orientation": "unspecified",
"name": "com.example.learn123.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "$string:entry_MainAbility",//标题栏上的文字
"type": "page",//page、service、data三种
"launchType": "standard",//或者是singleton单例模式
"visible": true
}
页面导航
统一page页面导航
首先在Ability中注册路由,如
super.addActionRoute("abilityslice1", AbilitySlice1.class.getName()); |
名字需要在config.json中的actions中注册
然后使用present进行跳转Intent intent = new Intent();
present(new AbilitySlice1(), intent);
如果希望带返回值的跳转,则使用presentForResult
Intent intent = new Intent(); |
然后原页面可以使用onResult处理返回值
@Override |
鸿蒙管理不同的slice是通过栈的方式,跳转时如果在栈中已经存在,那么会弹出在他上面的。
例如:Ability1进栈
Ability2进栈
Ability3进栈
现在栈中: Abiilty3 Ability2 Ability1
然后跳转到Ability1,栈的情况变为: Ability1
也就是说Ability1中的内容还是老的内容
Page之间的跳转
page之间的跳转可以通过startAbility()或startAbilityForResult()方法,获得返回结果的回调为onAbilityResult()
Intent intent = new Intent(); |
此外,如果某个名字使用addActionRoute("name", ...)
全局注册,那么我们可以直接跨Ability跳转intent.setAction("secondslice1");
startAbility(intent);
生命周期
- onStart(): 首次创建时触发
- onActive(): 获得焦点时
- onInactive(): 失去焦点时
- onBackground(): 转到后台时
- onStop(): 销毁时
AbilitySlice和page具有相同的生命周期。
Service Ability
启动Service有两种方式
- 通过startAbility()启动
- 通过connectAbility()启动,客户端可以通过disconnectAbility()断开连接
Service和Page不同的是它分为本地和远程两端。启动本地的方式和Page一样,启动远程的方式为
Operation operation = new Intent.OperationBuilder() |
远程连接Service
startAbility和stopAbility适合于时间很短并且交互量不大的场景,例如按钮的开关。而长时间则需要connect进行连接,如遥控器调节音量
步骤:
在config.json中申请权限,将reqPermissions添加到module中
"module":{
"package": "com.cangjie.jsabilitydemo",
"name": ".MyApplication",
"deviceType": [...],
"distro": {"deliveryWithInstall": true},
"abilities": [...],
"js": [...],
"reqPermissions": [{
{
//访问分布式数据
"name": "ohos.permission.DISTRIBUTED_DATASYNC"
},
{
//访问服务总线的绑定服务
"name": "ohos.permission.servicebus.ACCESS_SERVICE"
},
{
//访问服务总线的服务接入权限
"name": "ohos.permission.servicebus.BIND_SERVICE"
},
{
//访问分布式设备状态相关权限
"name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"
},
{
//分布式设备信息获取权限
"name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"
},
{
//获取Bundle信息权限
"name": "ohos.permission.GET_BUNDLE_INFO"
}
}]//添加
}同时我们还需要在MainAbility中获取权限
public void onStart(Intent intent)
{
requestPermissionsFromUser(new String[]{
"ohos.permission.DISTRIBUTED_DATASYNC",
"ohos.permission.servicebus.BIND_SERVICE",
"ohos.permission.servicebus.ACCESS_SERVICE"
], 0);
super.onStart(intent);
super.setMainRoute(MainAbilitySlice.class.getName());
}获取设备信息
public class DeviceUtil
{
public interface ISelectResult
{
void onSelectResult(String deviceId);
}
//获得设备列表并进行相关操作
public static void getOnlineDeviceInfo(ISelectResult listener)
{
List<DeviceInfo> onlineDevices = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
if(onlineDevices.isEmpty())
{
listener.onSelectResult(null);
return;
}
int numDevices = onlineDevices.size();
ArrayList<String> deviceIds = new ArrayList<>(numDevices);
ArrayList<String> deviceNames = new ArrayList<>(numDevices);
onlineDevices.forEach((device)->{
deviceIds.add(device.getDeviceId());
deviceNames.add(device.getDeviceName());//获得设备名
});
String selectDeviceId = deviceIds.get(0);
listener.onSelectResult(selectDeviceId);//选择第一个设备
}
}
//使用
DeviceUtil.getOnlineDeviceInfo(new DeviceUtil.ISelectResult(){
@Override
public void onSelectResult(String deviceId)
{
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder()
.withDeviceId(deviceId)
.withBundleName("com.charjedu.ability_demo")
.withAbilityName(".RemoteServiceAbility")
.build();
intnet.setOperation(operation);
connectAbility(intent, conn);
}
});创建本地代理
public class MyRemoteProxy implements IRemoteBroker
{
private static final int COMMAND_PLUS = IRemoteObject.MAX_TRANSACTION_ID;
private static final int ERR_OK = 0;
private final IRemoteObject remote;
public MyRemoteProxy(IRemoteObject remote)
{
this.remote = remote;
}
//返回远程对象,需要实现
public IRemoteObject asObject()
{
return remote;
}
//自定义的Service Ability方法
public int plus(int a, int b)
{
MessageParce1 data = MessageParce1.obtain();
data.writeInt(a);
data.writeInt(b);
MessageParce1 reply = MessageParce1.obtain();
//同步接收
MessageOption option = new MessageOption(MessageOption.TF_SYNC);
int result = 0;
try
{
//发送信息到远程,reply是远程返回的结果
//COMMAND_PLUS是用来标识当前是什么操作
remote.sendRequest(COMMAND_PLUS, data, reply, option);
int ec = reply.readInt();
if(ec != ERR_OK)
{
throw new RemoteException();
}
result = reply.readInt();
}catch(RemoteException e)
{
e.printStackTrace();
}
return result;
}
}IRemoteObject是connectAbility的回调中
connectAbility(new Intent(), new IAbilityConnection() {
@Override
public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int i) {
}
@Override
public void onAbilityDisconnectDone(ElementName elementName, int i) {
}
});创建远程代理
public class MyRemote extends RemoteObject implements IRemoteBroker
{
private static final int COMMAND_PLUS = IRemoteObject.MAX_TRANSACTION_ID;
private static final int ERR_OK = 0;
private static final int ERROR = -1;
public MyRemote()
{
super("my_remote");
}
public IRemoteObject asObject()
{
return this;
}
public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option)throws RemoteException
{
if(code != COMMAND_PLUS)
{
reply.writeInt(ERR_OK);
return false;
}
int v1 = data.readInt();
int v2 = data.readInt();
int rs = v1 + v2;
reply.writeInt(ERR_OK);
reply.writeInt(rs);
return true;
}
}- 创建远程Service Ability
public class RemoteServiceAbility extends Ability
{
private MyRemote remote = new MyRemote();
//返回远程对象
IRemoteObject onConnect(Intent intent)
{
return remote;
}
}前台Service Ability
一般情况下,Service都是在后台运行的,并且后台的优先级都是比较低的,资源不足时可能回收后台运行的Service
如果希望应用一直运行,便需要使用前台Service。前台Service会有一个保持运行的图标在前台显示。
想要启动前台服务,需要开启ohos.permission.KEEP_BACKGROUND_RUNNING
。并且在配置文件中添加backgroundModes参数,最后在onStart中调用keepBackgroundRunning并且在onStop中调用cancelBackgroundRunning停止前台Service
public void onStart(Intent intent) |
Data Ability
url
鸿蒙url的组成为Scheme://[authority]/[path][?query][#fragment]
- scheme: 协议名,固定为dataability
- authority: 设备id,如果为跨设备场景,则为目标设备的id,如果是本地设备,则无需填写
- path: 路径
DataAbilityHelper
DataAbilityHelper可以访问当前应用和其他应用提供的共享数据,它需要ohos.permission.READ_USER_STORAGE
和ohos.permission.WRITE_USER_STORAGE
权限。
- DataAbilityHelper.creator(this): 创建DataAbilityHelper
- openFile(Uri, String mode): 打开文件,mode有r、w、rw、wt(覆盖写)、wa(追加写)、rwt
- query(Uri uri, String[] columns, DataAbilityPerdicates): 查询
- insert(Uri uri, ValuesBucket value): 向数据库中插入单条数据
- batchInsert(Uri uri, ValuesBucket[] values)
- delete(Uri uri, DataAbilityPredicates predicates)
- update(…)
- executeBatch(ArrayList\
operations): 批量操作