CH4-armonyOS核心概念
作者:互联网
文章目录
前言
一个典型的HarmonyOS应用应该有与用户交互的界面,完成应用功能的业务逻辑
和需要处理的业务数据
。简单来说就是用户通过应用看到什么,通过应用能做什么以及对什么东西做。当然,对于一个复杂应用,不会只有一个可视化页面,会包含承载很多功能的显示处理模块,这些功能模块需要进行跳转切换。
目标
- 理解Ability的核心理念
- 熟悉Page Ability和Service Ability的运作方式
- 掌握使用Page Ability和Service Ability的构建及使用方法
- 能够通过Intent启动其他Page Ability和Service Ability。
1.Ability概念
-
Ability是HarmonyOS应用程序的重要组成部分,分为
FA
( Feature Ability)和PA
( Particle Ability)两种类型:- FA支持
Page Ability
: Page模板是FA唯一支持的模板,用于提供与用户交互的能力。 - PA支持
Service Ability
和Data Ability
: Service模板用于提供后台运行任务的能力;Data模板用于对外部提供统一的数据访问抽象。
- FA支持
-
FA需要提供ul用于与用户进行交互,HarmonyOs提供了Java Ul和JS uI两种uI框架:
- Java uI提供了细粒度的 uI编程接口,使
应用开发更加灵活
; - JS uI提了相对高层的UI描述使
应用开发更加简单
。
- Java uI提供了细粒度的 uI编程接口,使
-
针对轻量级智能穿戴( Lite Wearable ),现阶段只使用JS语言进行应用开发。
-
Ability是应用所具备能力的抽象,也是应用程序的重要组成部分。一个应用可以具备多种能力(即可以包含多个Ability ) ,HarmonyOS支持应用以Ability为单位进行部署。Ability可以分为FA( Feature Ability)和PA( Particle Ability)两种类型,每种类型为开发者提供了不同的模板,以便实现不同的业务功能。
Ability的分类
- FA支持Page Ability:
- Page模板是FA唯一支持的模板,用于提供与用户交互的能力。一个Page实例可以包含一组相关页面,每个页面用一个AbilitySlice实例表示。
- PA支持Service Ability和Data Ability:
- Service模板:用于提供后台运行任务的能力。
- Data模板:用于对外部提供统一的数据访问抽象。
- 在配置文件( config.json)中注册Ability时,可以通过配置Ability元素中的“type”属性来指定Ahilitv模板类型
2.Page Ability
2.1 Page与AbilitySlice
- Page模板(以下简称“Page”)是FA唯一支持的模板,用于提供与用户交互的能力。一个Page可以由一个或多个AbilitySlice构成,
AbilitySlice
是指应用的单个页面及其控制逻辑的总和
。 - 当一个Page由多个AbilitySltice共同构成时,这些AbilitySlice页面提供的业务能力应具有高度相关性。例如,新闻浏览功能可以通过一个Page来实现,其中包含了两个AbilitySlice:一个AbilitySlice用于展示
新闻列表
,另一个AbilitySlice用于展示新闻详情
。
2.2 Page Ability应用场景
- 相比于桌面场景,移动场景下应用之间的交互更为频繁。通常,单个应用专注于某个方面的能力开发,当它需要其他能力辅助时,会调用其他应用提供的能力。例如,外卖应用提供了联系商家的业务功能入口,当用户在使用该功能时,会跳转到通话应用的拨号页面。与此类似,支持不同Page之间的跳转,并可以指定跳转到目标Page中某个具体的AbilitySlice。
2.3 AbilitySlice路由配置
- 虽然一个Page可以包含多个AbilitySlice,但是Page进入前台时界面默认只展示一个AbilitySlice。默认展示的AbilitySlice是通过
setMainRoute()
方法来指定的。如果需要更改默认展示的AbilitySlice,可以通过addActionRoute()
方法为此AbilitySlice配置一条路由规则。此时,当其他Page实例期望导航到此AbilitySlice时,可以在Intent中指定Action。
setMainRoute&addActionRoute
public class MyAbility extends Ability {
@Override
public void onStart(Intent intent){
super.onStart(intent);
setMainRoute(MainSlice.class.getName());
addActionRoute("action.paybyAlipay",PayAlipaySlice.class.getName());
addActionRoute("action.paybyWechat",PayWechatSlice.class.getName());
}
}
注册action
. addActionRoute()方法中使用的动作命名,需要在应用配置文件( config.json )中注册
{
"module": {
"abilities": [
{
"skills":[
{
"actions":[
"action.paybyAlipay",
"action.paybyWechat"
]
}
]
………
}
]
..
}...
}
lntent intent = new Intent();
Operation operation = new lntent.OperationBuilder().withAction("action.paybyAlipay").build();
intent.setOperation(operation);
startAbility (intent);
2.4 Page Ability生命周期
- Page Ability生命周期回调- AbilitySlice生命周期
- Page Ability与AbilitySlice生命周期关联
- ·
系统管理
或用户操作
等行为均会引起Page实例在其生命周期的不同状态之间进行转换。 - Ability类提供的回调机制能够让Page及时感知外界受化,从而正确的应对状态的变化 (如释放资源),这有助于提升应用的性能和稳定性
onStart()
·当系统首次创建Paqe实例时,触发该回调。对于一个Page实例,该回调在其生命周期过程中仅触发一次
,Page在该逻辑后将进入INACTIVE状态。开发者必须重写该方法
,并在此配置默认展示的AbilitySlice。
@Override
public void onStart(Intent intent){super.onStart(intent);
super.setMainRoute(FooSlice.class.getName());}
onActive()
- Page会在进入INACTIVE状态后来到前台,然后系统调用此回调。Page在此之后进入ACTIVE状态,该状态是应用与用户交互的状态。
- Page将保持在此状态,除非某类事件发生导致Page失去焦点,比如
用户点击返回键
或导航到其他Page
。当此类事件发生时,会触发Page回到INACTIVE状态,系统将调用onInactive()回调。 - 此后,Page可能重新回到ACTIVE状态,系统将再次调用onActive()回调。因此,开发者通常需要成对实onActive()onInactive(),并在onActive()中获取在onInactive()中被释放的资源。
- Page将保持在此状态,除非某类事件发生导致Page失去焦点,比如
onlnactive&onBackground
- onInactive(): 当Page失去焦点时,系统将调用此回调,此后Page进入INACTIVE状态。开发者可以在此回调中实现Page失去焦点时应表现的恰当行为。
- onBackground(): 如果Page不再对用户可见,系统将调用此回调通知开发者用户进行相的资源释放,此后Page进入BACKGROUND状态。开发者应该在此回调中释放Page不可见时无用的资源,或在此回调中执行较为耗时的状态保存操作。
onForeground()
- 处于
BACKGROUND
状态的Page仍然驻留在内存中,当重新回到前台时(比如用户重新导航到此Page),系统将先调用onForeground()回调通知开发者,而后Page的生命周期状态回到INACTIVE状态。开发者应当在此回调中重新申请在onBackground()中释放的资源,最后Page的生命周期状态进一步回到ACTIVE状态,系统将通过onActive()回调通知开发者用户。
onStop()
- 系统将要销毁Page时,将会触发此回调函数,通知用户进行系统资源的释放。销毁Page的可能原因包括以下几个方面:
- 用户通过
系统管理能力
关闭指定Page,例如使用任务管理器关闭Pageo 用户行为
触发Page的terminateAbility()方法调用,例如使用应用的退出功能。配置变更
导致系统暂时销毁Page并重建。- 系统出于
资源管理目的
,自动触发对处于BACKGROUND状态Page的销毁。
- 用户通过
2.5 AbilitySlice生命周期
- AbilitySlice作为Page的组成单元,其生命周期是依托于其所属Page生命周期的。AbilitySlice和Page具有相同的生命周期状态和同名的回调,当Page生命周期发生变化时,它的AbilitySlice也会发生相同的生命周期变化。此外,AbilitySlice还具有独立于Page的生命周期变化,这发生在同一Page中的AbilitySlice之间导航时,此时Page的生命周期状态不会改变。
实例化
- AbilitySlice生命周期回调与Page的相应回调类似,由于AbilitySlice承载具体的页面,开发者必须
重写AbilitySlice的onStart()
回调,并在此方法中通过setUlContent()
方法设置页面。 - AbilitySlice实例创建和管理通常由应用负责,系统仅在特定情况下会创建AbilitySlice实例。例如,通过导航启动某个AbilitySlice时,是由系统负责实例化;
- 但是在同一个Page中不同的AbilitySlice间导航时则
由应用负责实例化
@Override
protected void onStart(Intent intent){
super.onStart(intent);
setUlContent(ResourceTable.Layout_main_layout);
}
生命周期关联
- 当AbilitySlice处于前台且具有焦点时,其生命周期状态随着所属Page的生命周期状态的变化而变化。当一个Page拥有多个AbilitySlice时,
- 例如:MyAbility下有FooAbilitySlice和BarAbilitySlice,当前FooAbilitySlice处于前台并获得焦点,并即将导航到BarAbilitySlice>,在此期间的生命周期状态变化顺序为:
- FooAbilitySlice从ACTIVE状态变为INACTIVE状态。
- BarAbilitySlice则从INITIAL状态首先变为INACTIVE状态,然后变为ACTIVE状态(假定此前BarAbilitySlice未曾启动)。
- FooAbilitySlice从INACTIVE状态变为BACKGROUND状态。
生命周期变化
- 对应两个slice的生命周期方法回调顺序为:
- FooAbilitySlice.onInactive() --> BarAbilitySlice.onStart() -->BarAbilitySlice.onActive() -->FooAbilitySlice.onBackground()
- 在整个流程中,MyAbility始终处于ACTIVE状态。但是,当Page被系统销毁时,其所有已实例化的AbilitySlice将联动销毁,而不仅是处于前台的AbilitySlice。
- 系统为每个Page维护了一个AbilitySlice实例栈,每个进入前台的AbilitySlice实例均会入栈。当开发者在调用present()或presentForResult()时指定的AbilitySlice实例已经在栈中存在时,则栈中位于此实例之上的AbilitySlice均会出栈并终止其生命周期。
- 前面的示例代码中,导航时指定的AbilitySlice实例均是新建的,即便重复执行此代码(此时作为导航目标的这些实例是同一个类),也不会导致任何AbilitySlice出栈。
AbilitySlice实例栈
AbilitySlice间导航
同一Page内导航
·当发起导航的AbilitySlice和导航目标的AbilitySlice处于同一个Page时,您可以通过present()
方法实现导航。
@Override
protected void onStart(Intent intent){
Button button = ...;
button.setClickedListener(listener -> present(new TargetSlice(), newlntent()));
}
AbilitySlice间数据传递
- 如果开发者希望在用户从导航目标AbilitySlice返回时,能够获得其返回结果,则应当使用
presentForResult()
实现导航。用户从导航目标AbilitySlice返回时,系统将回调onResult()
来接收和处理返回结果,开发者需要重写该方法。返回结果由导航目AbilitySlice在其生命周期内通过setResult()进行设置。
源AbilitySlice
@Override
protected void onStart(Intent intent){
..
Button button = ..;
button.setClickedListener(listener -> presentForResult(new TargetSlice(), new Intent(),0));
..
}
@Override
protected void onResult(int requestCode,Intent resultlntent) {
if (requestCode == 0) {
//Process resultlntent here.
}
}
不同Page间导航
-
不同Page中的AbilitySlice相互不可见,因此无法通过present()或presentForResult()方法直接导航到其他Page的AbilitySlice。AbilitySlice作为Page的内部单元,以action的形式对外暴露,因此可以通过配置Intent的Action导航到目标AbilitySlice。
-
Page间的导航可以使用
startAbility()
或startAbilityForResult()
方法,获得返回结果的回调为onAbilityResult()
。在Ability中调用setResult()
可以设置返回结果。
3.Service Ability
- ·基于
Service
模板的Ability (以下简称“Service”)主要用于后台运行任务(如执行音乐播放、文件下载等),但不提供用户交互界面。Service可由其他应用或Ability启动,即使用户切换到其他应用,Service仍将在后台继续运行。 - Service是单实例的。在一个设备上,相同的Service只会存在一个实例。如果多个Ability共用这个实例,只有当与Service绑定的所有Ability都退出后,Service才能够退出。由于Service是在主线程里执行的,因此,如果在Service里面的操作时间过长,开发者必须在Service里创建新的线程来处理(详见线程间通信),防止造成主线程阻塞,应用程序无响应。
3.1 创建Service
- ·创建Ability的子类,实现Service相关的生命周期方法。Service也是一种Ability,Ability为Service提供了以下生命周期方法,用户可以重写这些方法来添加自己的处理。
onStart()
: 该方法在创建Service的时候调用,用于Service的初始化。在Service的整个生命周期只会调用一次,调用时传入的Intent应为空。onCommand()
: 在Service创建完成之后调用,该方法在客户端每次启动该Service时都会调用,用户可以在该方法中做一些调用统计、初始化类的操作。
onConnect()
- 在Ability和Service连接时调用,该方法返回lRemoteObject对象,用户可以在该回调函数中生成对应Service的IPC通信通道,以便Ability与Service交互。Ability可以多次连接同一个Service,系统会缓存该Service的IPC通信对象,只有第一个客户端连接Service时,系统才会调用Service的onConnect方法来生成IRemoteObject对象,而后系统会将同一个RemoteObject对象传递至其他连接同一个Service的所有客户端连接,而无需再次调用onConnect方法。
onDisconnect&onStop
- onDisconnect():在Ability与绑定的Service断开连接时调用。
- onStop()︰在Service销毁时调用。Service应通过实现此方法来清理任何资源,如关闭线程、注册的侦听器等。
public class ServiceAbility extends Ability {
@Override
public void onStart(lntent intent){
super.onStart(intent);
}
@Override
public void onCommand(Intent intent, boolean restart, intstartld) {
super.onCommand(intent, restart, startld);
}
@Override
public lRemoteObject onConnect(Intent intent){
super.onConnect(intent);
return null;
}
}
@Override
public void onDisconnect(Intentintent) {
super.onDisconnect(intent);
}
@Override
public void onStop() {
super.onStop();
}
3.2 注册Service
Service也需要在应用配置文件中进行注册,注册类型type需要设置为service
{
"module": {
"abilities": [
{
"name": ".ServiceAbility",
"type": "service",
"visible": true
}
]
}
}
3.3 启动Service
-
Ability为开发者提供了
startAbility()
方法来启动另外一个Ability。因为Service也是Ability的一种,开发者同样可以通过将Intent传递给该方法来启动service。不仅支持启动本地Service,还支持启动远程Service。 -
开发者可以通过构造包含Deviceld、BundleName与AbilityName的Operation对象来设置目标Service信息。这三个参数的含义如下:
Deviceld
: 表示设备ID。如果是本地设备,则可以直接留空;如果是远程设备,可以通
过ohos.distributedschedule.interwork.DeviceManagerr提供的
getDeviceList
获取设备列表;BundleName
: 表示包名称;AbilityName
:表示待启动的Ability名称。
本地Service启动
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder().withDeviceld("").withBundleName("com.huawei.hiworld.himusic").withAbilityName("com.huawei.hiworld.himusic.ServiceAbility").build();
intent.setOperation(operation);
startAbility(intent);
远程设备Service启动
Operation operation = new Intent.OperationBuilder()
.withDeviceld("deviceld")
.withBundleName("com.huawei.hiworld.himusic")
.withAbilityName("com.huawei.hiworld.himusic.ServiceAbility")//设置支持分布式调度系统多设备启动的标识
.withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE).build();
Intent intent = new Intent();
intent.setOperation(operation);
startAbility(intent);
startAbility的两种场景
执行上述代码后,Ability将通过startAbility()
方法来启动Service
- 如果Service尚未运行,则系统会先调用
onStart()
来初始化Service,再回调Service的onCommand()
方法来启动Service; - 如果Service正在运行,则系统会直接回调Service的
onCommand()
方法来启动Service。
3.4 连接Service
- 如果Service需要与Page Ability或其他应用的Service Ability进行交互,则应创建用于连接的Connection。Service支持其他Ability通过
connectAbility()
方法与其进行连接。- 在使用connectAbility()处理回调时,需要传入目标Service的
Intent
与AbilityConnection的实例
。AbilityConnection提供了两个方法供开发者实现: - onAbilityConnectDone()用来处理连接的回调,
- onAbilityDisconnectDone()用来处理断开连接的回调。
- 在使用connectAbility()处理回调时,需要传入目标Service的
3.5 生命周期
- 与Page类似,Service也拥有生命周期。根据调用方法的不同,其生命周期有以下两种路径:
启动Service
: 该Service在其他Ability调用startAbility()
时创建,然后保持运行。其他Ability通过调用stopAbility()
来停止Service,Service停止后,系统会将其销毁。 连接Service
: 该Service在其他Ability调用connectAbility()
时创建,客户端可通过调用disconnectAbility()
断开连接。多个客户端可以绑定到相同Service,而且当所有绑定全部取消后,系统即会销毁该Service。
Service回调函数
前台Service
- 一般情况下,Service都是在后台运行的,后台Service的优先级都是比较低的,当资源不足时,系统有可能回收正在运行的后台Service。
- 在一些场景下(如播放音乐),用户希望应用能够一直保持运行,此时就需要使用前台Service。前台Service会始终保持正在运行的图标在系统状态栏显示。
- 使用前台Service并不复杂,开发者只需在Service创建的方法里,调用
keepBackgroundRunning()
将Service与通知绑定。调用keepBackgroundRunning()
方法前需要在配置文件中声明ohos.permission.KEEP_BACKGROUND_RUNNING权限
backgroundModes参数
。 - 在onStop()方法中调用
cancelBackgroundRunning()
方法可停止前台service。
//创建通知,其中1005为notificationld
NotificationRequest request = new NotificationRequest(1005);
NotificationRequest.NotificationNormalContent content = new NotificationRequest.NotificationNormalContent();
content.setTitle("title").setText("text");
NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(content);
request.setContent(notificationContent);
//绑定通知,1005为创建通知时传入的notificationldkeepBackgroundRunning(1005, request);
{
"name": ".ServiceAbility",
"type": "service",
"visible": true,
"backgroundModes":["dataTransfer" ,"location"]
}
4.Intent
- lntent是对象之间传递信息的载体。例如,当一个Ability需要启动另一个Ability时,或者一个AbilitySlice需要导航到另一个AbilitySlice时,可以通过Intent指定启动的目标同时携带相关数据。Intent的构成元素包括
Operation
与Parameters
。
内部结构
lntent的分类
- 当Intent用于发起请求时,根据指定元素的不同,分为两种类型:
- 如果同时指定了
BundleName
与AbilityName
,则根据Ability的全称(例如,“ com.demoapp.FooAbility”)来直接启动应用,称为显式lntent
。 - 如果未同时指定BundleName和AbilityName,则根据Operation中的其他属性来启动应用,称为
隐式Intent
Intent设置属性时,必须先使用Operation来设置属性。如果需要新增或修改属性,必须在设置Operation后再执行操作。
- 如果同时指定了
显式lntent的使用
- 通过构造包含BundleName与AbilityName的Operation对象,可以启动一个Ability、并导航到该Ability。作为处理请求的对象,会在相应的回调方法中接收请求方传递的Intent对象。以导航到另一个Ability为例,导航的目标Ability可以在其
onStart()
回调的参数中获得intent对象
Intent intent = new Intent();
/通过Intent中的OperationBuilder类构造operation对象,指定设备标识(空串表示当前设备)、应用包名、Ability名称
Operation operation = new lntent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.demoapp")
.withAbilityName("com.demoapp.FooAbility").build();
//把operation设置到intent中intent.setOperation(operation);startAbility(intent);
使用Intent进行数据传递
- 如果FA1启动了FA2,且FA1需要向FA2中进行数据传递,以控制FA2的显示内容,这时可以通过Intent对象来携带数据。
- 典型的例子是通讯录,通讯录主页上显示多条联系人,单击某个联系人,则显示联系人的详情,每个人的详情页显示的内容不一样,但实际上是同一个FA,只是其内容受控于主页FA。
数据传输示例
·设FA1和FA2之间的Intent名为secondIntent,则数据传输代码如下:
- FA1: secondIntent.setParam(“text”,“passedvalue”);
- 通过setParam可以在Intent中设置传递给下一个页面的数据,这里是传递了一个字符串,名为text,值为passedvalue
- FA2: text.setText(intent.getStringParam(“text”);
- 在第二个页面的onStart ( intent)方法中可以调用getStringParam方法将字符串text值读出来
隐式lntent的使用
- 有些场景下,开发者需要在应用中使用其他应用提供的某种能力,而不感知提供该能力的具体是哪一个应用。例如开发者需要通过浏览器打开一个链接,而不关心用户最终选择哪一个浏览器应用,则可以通过operation的其他属性(除BundleName与AbilityName之外的属性)描述需要的能力。如果设备上存在多个应用提供同种能力,系统则弹出候选列表,用户选择由哪个应用处理请求。以下示例展示使用Intent跨Ability天气信息。
请求方
- 在Ability中构造Intent以及包含Action的Operation对象,并调用
startAbilityForResult()
方法发起请求。然后重写onAbilityResult()
回调方法,对请求结果进行处理。
private void queryWeather() {
lntent intent = new Intent();
Operation operation = new Intent.OperationBuilder().withAction(Intent.ACTION_QUERY_WEATHER).build();
intent.setOperation(operation);
startAbilityForResult(intent, REQ_CODE_QUERY_WEATHER)
}
@Override
protected void onAbilityResult(int requestCode, int resultCode, Intent resultData){
switch (requestCode){
case REQ_CODE_QUERY_WEATHER: //Do something with result.
...
return;
default:
...
}
}
处理方
- 配置文件修改:作为处理请求的对象,首先需要在配置文件中声明对外提供的能力,以便系统据此找到自身并作为候选的请求处理者。
{
"module": {
"abilities": [
{
"skills":[
{
"actions":["ability.intent.QUERY_WEATHER"]
}
]
}
]
}
}
- 在Ability中
配置路由
以便支持以此action导航到对应的AbilitySlice
@Override
protected void onStart(Intent intent){
addActionRoute(Intent.ACTION_QUERY_WEATHER, DemoSlice.class.getName());
}
- 在Ability中处理请求,并调用
setResult()
方法暂存返回结果。
Override
protected void onActive() {
Intent resultIntent = new Intent();setResult(0, resultIntent);
}
5.访问后台服务获取电池电量Demo
1.建立前台FA显示电量信息:
前台FA有两个可视化元素,一个Text,用来显示获得的手机电量,一个Button,用来触发调用后台服务事件。
<Text
ohos:id="$+id:text_helloworld"
ohos:height="match_content"
ohos:width="match_content"
ohos:background_element="$graphic:background_ability_main"
ohos:layout_alignment="horizontal_center"
ohos:text="$string:mainability_HelloWorld"
ohos:text_size="20vp"
>
前端搭建
<Button
ohos:id="$+id:button_battery"
ohos:height="match_content"
ohos:width="match_content"
ohos:background_element="$graphic:background_ability_main"
ohos:layout_alignment="horizontal_center"
ohos:text="BatteryInfo"
ohos:text_size="30vp"
>
2.连接后台服务:
调用connectAbility(intent,connection)
连接后台服务,其中Intent的operation
参数已经指明服务所在设备id,包名和包含的能力名称,参数connection
为AbilityConnection类型。
private void startBatteryService() {
Operation operation = new Intent.OperationBuilder().withDeviceld("")
.withBundleName("com.whu.batteryjavacallpa")
.withAbilityName("com.whu.batteryjavacallpa.Batterylnfo").build();
Intent intent = new Intent();
intent.setOperation(operation);
connectAbility(intent, connection);
}
3.建立后台服务BatteryInfo
新建Service Ability,该服务没有界面,纯粹提供电量读取服务功能。该服务中除了基本的电量获取函数getBatteryInfo,最重要是完成Service Ability的重载函数onConnect(Intent intent)
。意味着当前台FA连接后台服务时会触发onConnect事件,在该事件中获取电量。
private String getBatteryInfo() {
StringBuilder stringBuilder = new StringBuilder();
boolean isCharging = getChargingStatus();
double batteryValue = getBatteryLevel();
stringBuilder
.append("电量还剩")
.append(batteryValue+"% ,"+ System.lineSeparator)).append("正在充电: "")
.append(isCharging);
}
return stringBuilder.toString();
}
lRemoteObject接口
@Override
public IRemoteObject onConnect(Intent intent){
MyRemote thisRemote = new MyRemote();
thisRemote.butery = getBatterylnfo();
return thisRemote;
}
4.建立IRemoteObject子类MyRemote的实例
,并返回给onConnect函数∶新建MyRemote类,MyRemote类为LocalRemoteObject的子类,而LocalRemoteObject为RemoteObject的子类。返回的MyRemote的实例会返回到客户端。
public class MyRemote extends LocalRemoteObject {
public String butery = "";//添加变量获取电量返回值
public MyRemote() {
super();
}
}
5.前台FA调用后台服务函数
,显示电量:客户端重载IAbilityConnection
类的函数onAbilityConnectDone(ElementName elementName,lRemoteObject iRemoteObject,int resultCode)
,该函数在客户端与服务器连接建立好后会触发,服务端返回
lRemoteObject对象。解析该对象,得到手机电量。
private lAbilityConnection connection = new IAbilityConnection() {
@Override
public void onAbilityConnectDone(ElementName elementName, IKemoteubject likeolevu]eul, mresultCode){
HiLog.info(LABEL_LOG, "%{public]s" , "onAbilityConnectDone resultCode : " + resultCode);
MyRemote clientRemote = (MyRemote) iRemoteObject;
Text txt = (Text)findComponentByld(ResourceTable.ld_text_helloworld);
txt.setText(clientRemote.butery);
Button btn = (Button)findComponentByld(ResourceTable.ld_button_battery);
btn.setText("电池状态");
}
}
private lAbilityConnection connection = new IAbilityConnection() {
@Override
public void onAbilityConnectDone(ElementName elementName, IKemoteubject likeolevu]eul, mresultCode){
HiLog.info(LABEL_LOG, "%{public]s" , "onAbilityConnectDone resultCode : " + resultCode);
MyRemote clientRemote = (MyRemote) iRemoteObject;
Text txt = (Text)findComponentByld(ResourceTable.ld_text_helloworld);
txt.setText(clientRemote.butery);
Button btn = (Button)findComponentByld(ResourceTable.ld_button_battery);
btn.setText("电池状态");
}
}
[外链图片转存中…(img-OtjTEBCm-1642394987751)]
标签:Ability,Service,armonyOS,核心,AbilitySlice,CH4,Intent,intent,Page 来源: https://blog.csdn.net/weixin_46227276/article/details/122537548