考点说明
1.idl
在开发HarmonyOS应用时,如果客户端和服务端需要跨进程通信,可以使用idl来定义两者均认可的编程接口。
idl是鸿蒙的接口描述语言,其全称是Interface Definition Language。在开发HarmonyOS应用时,idl主要用于跨设备连接Service。当需要跨设备连接到Service并与之进行交互时就涉及到了跨进程通信。跨进程通信意味着在一个进程中访问另一个进程的数据或调用另一个进程的方法。在客户端和服务端需要跨进程通信时,idl用于定义两者均认可的编程接口。因此,这道题的描述是正确的。
通常把接口的提供方称为服务端,把接口的调用方称为客户端。客户端通过连接服务端的Service来与之进行交互。
我们可以创建一个idl文件试试看。在HarmonyOS工程中,右键点击模块目录,选择New>Idl File,直接输入idl文件的名称,例如:IRemoteAbility,然后点击按钮OK。DevEco Studio在相应模块的src>main路径下生成了idl文件夹,并按照对应模块的包名生成了同样的目录结构及IDL文件。打开IRemoteAbility.idl,删除其中所有的注释,然后声明一个方法,用于两个整数相加。方法的返回值类型是int,方法名是plus,两个形参分别是num1和num2,都是int类型的。点击右边栏的Gradle,在打开的工具窗口中先展开对应的模块entry,然后展开Tasks,然后展开ohos:debug,最后在展开的列表中双击compileDebugIdl,从而对文件IRemoteAbility.idl进行编译。编译完成后,在目录build → generated → source → Idl → 包名下,生成了三个文件,分别对应:接口IRemoteAbility、客户端的代理类RemoteAbilityProxy、服务端的桩类RemoteAbilityStub。
2.Service
-
在调用方法startAbility()时,会根据指定的Intent对象启动Service。 -
如果Service尚未运行,那么系统会先创建Service并回调方法onStart()来初始化Service,再回调Service的方法onCommand()来启动Service。 -
如果Service正在运行,那么系统会直接回调Service的方法onCommand()来启Service。 -
方法onStart()在系统创建Service时被回调,用于Service的初始化。 -
在Service的整个生命周期中方法onStart()只会被系统回调一次。 -
方法onCommand()在系统创建完Service之后被回调。每次启动Service方法onCommand()都会被系统回调。开发者可以在该方法中做一些调用统计、初始化类的操作。 -
Service一旦运行就会一直保持在后台,除非必须回收内存资源,否则系统不会停止或销毁Service。 -
开发者既可以在Service中调用方法terminateAbility()停止Service,也可以在其他Ability中调用方法stopAbility()来停止Service。一旦调用停止Service的方法,系统便会尽快销毁Service。方法onStop()在系统销毁Service之前被回调。开发者可以在该方法中清理资源,例如:关闭线程、注销侦听器、等等。
前台Service的应用和Service的基本概念: 一般情况下,Service都是在后台运行的,后台Service的优先级都是比较低的,当资源不足时,系统有可能回收正在运行的后台Service。但在一些场景下(如播放音乐),用户希望应用能够一直保持运行,此时就需要使用前台Service。前台Service会始终保持正在运行的图标在系统状态栏显示。
使用前台Service并不复杂,只需要三步:
第一步,创建通知。首先创建NotificationRequest的实例,然后创建NotificationNormalContent的实例并设置通知的内容。
第二步,绑定通知。我们调用keepBackgroundRunning()将Service与通知绑定。
第三步,添加配置。在配置文件中声明ohos.permission.KEEP_BACKGROUND_RUNNING权限,同时还需要在配置文件中添加对应的backgroundModes参数。需要注意的是,abilities下的visible表示Ability是否可以被其他应用调用,默认是false,表示不能被其他应用调用。
3.关系型数据库
关系型数据库(Relational Database,RDB)是一种基于关系模型来管理数据的数据库。HarmonyOS关系型数据库基于SQLite组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满足复杂的场景需要。HarmonyOS提供的关系型数据库功能更加完善,查询效率更加高效。HarmonyOS关系型数据库对外提供通用的操作接口,底层使用SQLite作为持久化存储引擎,支持SQLite具有的所有数据库特性,包括但不限于事务、索引、视图、触发器、外键、参数化查询和预编译SQL语句。
如果不指定数据库的日志模式,那么系统默认日志方式是WAL(Write Ahead Log)模式。 如果不指定数据库的落盘模式,那么系统默认落盘方式是FULL模式。 HarmonyOS数据库使用的共享内存默认大小是2MB。
4.分布式接口
通过调用指定分布式接口实现跨设备能力。根据Ability模板及意图的不同,分布式任务调度向开发者提供了六种能力,分别是:启动远程FA、启动远程PA、关闭远程PA、连接远程PA、断开连接远程PA和FA跨设备迁移。
connectAbility() 接口提供连接指定设备上PA的能力,其中的参数Intent中指定待连接PA的设备deviceId、bundleName和abilityName。当连接成功后,通过在onAbilityConnectDone()回调中获取对端PA的服务代理。 disconnectAbility() 接口与connectAbility()接口相反,提供断开远程PA连接的能力。
startAbility() 接口提供启动指定设备上FA和PA的能力。 stopAbility() 接口提供关闭指定远程PA的能力。同样地,将指定待连接或待断开的设备deviceId、bundleName和abilityName封装到Intent中。
continueAbility( ) 接口提供将本地FA迁移到指定设备上的能力。在用户选择设备后,设备A将运行时的FA迁移到设备B,实现业务在设备间无缝迁移。
5.视频播放功能开发步骤
1、创建Player实例,可调用Player(Context context),创建本地播放器,用于在本设备播放。
2、构造数据源对象,并调用Player实例的setSource(Source source)方法,设置媒体源,代码示例如下
Player player = new Player(context);
File file = new File("/sdcard/test_audio.mp4");
FileInputStream in = new FileInputStream(file);
FileDescriptor fd = in.getFD();
Source source = new Source(fd);
player.setSource(source);
3、调用prepare(),准备播放。
4、(可选)构造IPlayerCallback,IPlayerCallback需要实现onPlayBackComplete和onError(int errorType, int errorCode)两个方法,实现播放完成和播放异常时做相应的操作。代码示例如下:
@Override
public void onPlayBackComplete() {
HiLog.info(TAG, "PlayerCallback onPlayBackComplete");
if (player != null) {
player.stop();
player = null;
}
}
@Override
public void onError(int errorType, int errorCode) {
HiLog.error(TAG, "PlayerCallback onError errorType: %{public}d, errorCode: %{public}d", errorType, errorCode);
}
5、调用play()方法,开始播放。
6、(可选)调用pause()方法和play()方法,可以实现暂停和恢复播放。
7、(可选)调用rewindTo(long microseconds)方法实现播放中的拖拽功能。
8、(可选)调用getDuration()方法和getCurrentTime()方法,可以实现获取总播放时长以及当前播放位置功能。
9、调用 stop()方法停止播放。
10、播放结束后,调用release()释放资源。
6.Java UI框架
-
应用中所有的用户界面元素都是由Component和ComponentContainer对象构成。首先用户界面元素统称为组件,而Component是界面中所有组件的基类。其次,标准布局类的组件一般继承自ComponentContainer。 -
组件树有且仅有一个根组件,其他组件有且仅有一个父节点,组件之间的关系受到父节点的规则约束。我们知道组件树是一个布局,它把Component和ComponentContainer以树状的层级结构进行组织,而树状的层次结构决定了它只有唯一的根结点,且除了根结点外的所有结点有且只有一个前驱。 -
在UI框架中,布局类组件的命名一般是以Layout结尾的,但诸如提供滑动翻页功能的PageSlider、提供内容滚动功能的ScrollView、提供翻转效果的PageFlipper都是间接继承自ComponentContainer,直接继承自StackLayout,它们的命名没有以Layout结尾。 -
完整的用户界面是一个布局,用户界面中的一部分也可以是一个布局,因为一个用户界面至少包含一个布局,且ComponentContainer可以作为容器容纳ComponentContainer对象,并对它进行布局。 -
在Java UI框架中,提供了两种编写布局的方式,一种方式是通过XML的方式声明布局,该方式是对布局和组件的属性与层级结构进行描述。另一种方式是通过代码的方式创建布局,此方式需要先分别创建组件和布局,再为这些对象设置合适的布局参数和属性值,当我们在DevEco Studio中使用模板创建一个项目时,项目会默认使用XML方式对布局进行声明。
7.JS UI框架
JS UI框架包括应用层(Application)、前端框架层(Framework)、引擎层(Engine)和平台适配层(Porting Layer)。如下图所示:
- Application应用层
表示开发者使用JS UI框架开发的FA应用,这里的FA应用特指JS FA应用。使用Java开发FA应用请参考Java UI框架。 - Framework
前端框架层主要完成前端页面解析,以及提供MVVM(Model-View-ViewModel)开发模式、页面路由机制和自定义组件等能力。 - Engine
引擎层主要提供动画解析、DOM(Document Object Model)树构建、布局计算、渲染命令构建与绘制、事件管理等能力。 - Porting Layer
适配层主要完成对平台层进行抽象,提供抽象接口,可以对接到系统平台。比如:事件对接、渲染管线对接和系统生命周期对接等。
8.布局
- DirectionalLayout是Java UI中的一种重要组件布局,对于此布局我们需要重点掌握两点
其一是布局的排列方向默认为垂直排列(vertical),且不会自动换行,超出部分不会显示。 其二是布局可以按比例分配子组件占父组件的大小,这里涉及两个XML属性,第一个是DirectionLayout的自有XML属性total_weight,表示所有子视图的权重之和,第二个是其组件所支持的XML属性weight,表示子组件的比重。 - DependentLayout设置依赖关系时,需要注意的属性优先级问题。在设置子组件与同级组件的相对关系时,需要注意优先级。
在left_of与start_of同时配置发生冲突时,start_of的优先级更高。此外,在设置子组件与父组件的相对关系时,也需要注意优先级。 在align_parent_start与align_parent_left同时配置发生冲突时,align_parent_start的优先级更高。 - StackLayout是组件可以重叠的框架布局,添加到这个布局中的视图都是以层叠的方式显示。第一个添加到布局中的视图显示在最底层,
- TableLayout使用表格的方式划分子组件,对于布局TableLayout我们需要重点掌握两个方面
其一是行数和列数的设置,即通过XML 属性column_count与row_count来设置行数和列数,默认为一列多行。 其二就是两种排列方式,第一种是align_edges,表示按边界对齐,第二种是align_contents,表示按边距对齐,默认为按边距对齐。 AdaptiveBoxLayout是自适应盒子布局,它主要用于多个同级别组件需要在不同屏幕尺寸设备上自动调整列数的场景。常用的方法有三个:
- 添加布局规则的方法addAdaptiveRule()
- 移除单个布局规则的方法removeAdaptiveRule()
- 移除所有布局规则的方法clearAdaptiveRules()
9.内外边距
内间距和外边距均为组件通用的XML属性,且内间距是padding,外边距是margin,它们两者的参数都是float类型,其单位默认为px。
margin的优先级比left_margin的优先级要高,同理,当margin属性与其它具体方向上的外边距属性同时配置并发生冲突时,只有margin属性的设置有效。请大家看这张图:
同时配置如果发生冲突时的优先级排序(从高到低)依次为:margin大于start_margin和end_margin,大于其它四个方向上的margin。特别需要注意的是,在设置内间距时,padding与具体方向上内间距属性同时配置时,也会发生冲突,此时padding的优先级要低于其他属性。请大家看这张图: 同时配置如果发生冲突时的优先级排序(从高到低)依次为:start_padding和end_padding大于其它四个方向上的padding,大于padding。总之,margin与padding的优先级规则是不一样的,请大家特别注意。
10.数字签名
HarmonyOS应用通过数字证书(.cer文件)和Profile文件(.p7b文件)来保证应用的完整性,数字证书和Profile文件可通过申请发布证书和Profile文件获取。申请数字证书和Profile文件前,首先需要通过DevEco Studio来生成密钥文件(.p12文件)和证书请求文件(.csr文件)。同时,也可以使用命令行工具的方式来生成密钥文件和证书请求文件。
密钥: 包含非对称加密中使用的公钥和私钥,存储在密钥库文件中,格式为.p12,公钥和私钥对用于数字签名和验证。
证书请求文件: 格式为.csr,全称为Certificate Signing Request,包含密钥对中的公钥和公共名称、组织名称、组织单位等信息,用于向AppGallery Connect申请数字证书。
数字证书: 格式为.cer,由华为AppGallery Connect颁发。
Profile文件: 格式为.p7b,包含HarmonyOS应用的包名、数字证书信息、描述应用允许申请的证书权限列表,以及允许应用调试的设备列表(如果应用类型为Release类型,则设备列表为空)等内容,每个应用包中均必须包含一个Profile文件。
build.gradle中生成的签名配置信息,如下图所示:
|