书名:鸿蒙八门:HarmonyOS应用开发
ISBN:978-7-115-59965-0
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
著 张方兴
责任编辑 赵 轩
人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
网址 http://www.ptpress.com.cn
读者服务热线:(010)81055410
反盗版热线:(010)81055315
鸿蒙HarmonyOS是一款自主研发、面向未来物联网技术的操作系统,虽然与Android操作系统有着相似之处,但其功能与特色也是值得开发者深入探索的。本书的主要目的是帮助不熟悉此系统的开发者循序渐进地掌握HarmonyOS的诸多关键特性,从HarmonyOS基础知识、Java UI框架,到Ability开发、HarmonyOS高级特性开发;从HarmonyOS数据管理、HarmonyOS与媒体、HarmonyOS与智能设备,到面向实战的仿微信程序开发、仿淘宝程序开发等。在本书的最后,还有整体的项目练习。通过对这本书的学习,读者可以初步掌握HarmonyOS应用开发的方法。
本书为读者提供了一个明确而清晰的HarmonyOS开发学习路线,帮助读者循序渐进,少走弯路。在学习完本书之后,读者会对HarmonyOS应用程序开发有一个较为整体的认知,通过反复练习后,可以轻松写出新闻资讯、电商等类型的简单应用程序。
在刚接触HarmonyOS时,我们总会将其与Android混为一谈,但是从技术方面角度来看,它们在相似之中又有诸多不同之处。如果不去仔细探索,总会觉着代码看起来都认识,但是抛开书本、文档,自己却无法顺利编写应用程序。因此,我在编写本书时,希望能够带领读者一边思考,一边实战,代码写得多了,自然就可以学以致用了。
本书从最基础的“Hello World”开始,由浅入深地讲解了超过40个小项目的实践方法,每个实战都有相应代码,您在实践前,可以按照本书封底所介绍的方式获取代码。
● Android程序员
● JavaScript程序员
● Java程序员
● 希望掌握HarmonyOS应用程序开发的程序员
● 各类院校相关专业的老师和学生
如果您在阅读本书时遇到任何技术问题,或者想要获取更多学习资源,以及希望和更多技术高手进行交流,可以加入笔者所创建的QQ群772927717(编程沟通学习交流群)。
感谢各位编辑的辛苦付出,非常感谢诸位对本书出版所做出的贡献与考量。感谢赵轩老师(本书责任编辑)在本书出版过程中的众多帮助。
由于个人水平有限,书中难免还会有错漏之处,小伙伴们如果发现问题或有任何意见,也可以到微信公众号(北漂程序员的吐槽人生)或邮箱(zhang_fangxing@163.com)与我联系。
2007年11月5日,Google公司正式向外界展示了名为Android的操作系统,并在当天宣布成立OHA(Open Handset Alliance,开放手机联盟)。
Google公司将Android系统的基础功能开源,并称之为AOSP(Android Open Source Project,Android开放源代码项目)。这是一个迷你版的Android系统,普通用户可以根据AOSP的代码编译出Android系统。普通用户与厂商可对AOSP的代码进行独立更改,编译成自己的Android系统,并进行闭源;也可向AOSP贡献相应代码,助其优化版本。
在诺基亚公司的塞班系统“横行”市场之时,Android系统开始蓬勃发展,市场占有率一路提升至80%,彼时的iOS系统、塞班系统、Windows Phone系统、黑莓系统完全没有任何抗衡能力,这其中大部分的“能量”基于Android系统的AOSP。
但是在此之后,Google公司开始出现两极分化的问题,即Android系统在市场上的成功,并非完全是Google公司的功劳,Google公司也无法完全掌控Android系统。毕竟对于Google公司来说,所有友商推出的Android系统都会影响Android市场占有率。所以Google公司不断精进自己的GMS(Google Mobile Service,谷歌移动服务),GMS是Google公司开发并推动Android的动力与基础。
GMS提供包括移动支付、搜索、语音搜索、联系人同步、日历同步、邮件、地图、街景、应用内购、账号同步、广告接口等一系列服务,以及应用商店(Google Play)。除此之外,GMS还提供一系列的底层接口和库文件,这样第三方应用程序就可以调用这些库文件和接口,以实现简化App(小程序)开发的目的。当然这也让大量依赖于GMS的App在失去了GMS的“光环”之后,就无法正常运行了。所以对于海外用户而言,GMS是手机生态中的必需品,若无GMS,那么外卖、打车、导航、聊天工具、移动支付等的相关软件可能无法正常运行,手机可能将处于一种半瘫痪的状态。
Google公司通过GMS统一应用渠道的出入口,达到协调Android系统与应用程序的目的。依据GMS的内嵌程度,Google公司对Android手机给予不同程度的授权,并把搭载Android系统的手机厂商大致分为3个大类别。
(1)免费使用Android系统,但完全不内嵌GMS。
(2)内嵌部分GMS,但手机不能使用Google公司的商标,手机内部可能有友商自主设计的服务框架。
(3)内嵌所有GMS,经过Google公司的审核后,得到Google公司的授权,可使用Google公司的商标。
然而国内大部分用户其实用不了GMS,因为国内无法连接Google公司的服务器,同时国内大多不允许使用VPN(Virtual Private Network,虚拟专用网络)进行连接。同时国内也衍生了大量不同的负责提供移动支付、搜索、语音搜索、软件商店、短信提醒、消息推送、账号验证的公司,这些公司提供了大量的API(Application Program Interface,应用程序接口)让第三方App使用。
对于手机厂商而言,如果希望Android手机内置GMS,那么必须通过Google公司的兼容性认证。手机厂商认证GMS的过程中,需要缴纳相应费用才能够得到Google公司的授权,得到授权之后才可以将GMS预装进手机之中。Android设备可以免费使用AOSP,但是安装GMS必须得到Google公司的认证。
当然,Google公司的认证并不是交钱就能通过的。Google公司对于软件获取用户隐私(包括联系人电话、短信、图片、存储空间)、是否调用了过多无用接口、是否浪费了过多流量、是否未经用户同意或诱导用户使用短信直接进行支付等相关内容都进行了相应测试。
HarmonyOS的定位以及概述在HarmonyOS Developer官网中有详细讲解,在此不做赘述。
HarmonyOS开源的基础内容被称为Open Harmony,也就是说Open Harmony对标的是AOSP。本书将使用Harmony统称HarmonyOS与Open Harmony。
HMS(Huawei Mobile Service,华为移动服务)对标的是GMS,其职责并无二致,HMS是华为公司为解除Google公司的限制所开发的项目。GMS有Google Play应用商店,而HMS有AppGallery应用商店。
对于学习Harmony开发的程序员来讲,Harmony开发分为两个方向,分别是应用开发方向以及设备开发方向,就像Android系统在市场上会有工业Android与框架Android两种分支。工业Android通常指工厂里的一些设备使用的Android系统,例如身份证识别手持端、门铃对讲系统、ATM(Automated Teller Machine,自动取款机)、嵌入式系统、电视机顶盒等。
学习工业与嵌入式开发的程序员为设备开发者,需要学习Open Harmony的内核系统文件,包括VFS、NFS、RAMFS、FAT、JFFS2、驱动、移植与相关标准等内容。值得一提的是2021年发布的Open Harmony2.0支持手机设备,支持手机设备之前Open Harmony只支持对嵌入式的一些开发板进行烧写与使用。目前支持Open Harmony烧写的开发板日益增多,例如Neptune、HiSpark系列等。这部分应用场景体现在智能家居物联网终端、智能穿戴设备、智慧大屏、汽车智能座舱、智能音响等常见物联网项目上。
仅以Harmony 2.0而言,无论是嵌入式方面还是应用程序方面,从本质上讲Harmony系统能做的事情Android都能做。但Harmony系统设计了许多诸如分布式存储、AI(Artificial Intelligence,人工智能)识别公有文字、分布式数据库、跨设备支持等新颖的内容。这些内容在任何其他操作系统上,都没有像Harmony一样把各种接口、路由、协议内容梳理好,Harmony让程序员只需要关注业务的实现而不用关心底层逻辑,可大大减少应用程序设计上的复杂度、难度和损耗时间。
到目前为止,Harmony系统的分布式思想与实现是当前市场上较为超前的内容。这个系统的目标是让万物实现真正的互联,兼容自动化驾驶、工业自动化、路由器、可穿戴设备、智能手机、亿级数据中心等设备。
Harmony 2.0发布会多次提到Harmony是分布式系统,但是很多人仍然没有理解Harmony理想的分布式世界。
在Harmony开发者教程中,含有分布式地图导航、分布式输入法、分布式游戏手柄、分布式邮件编辑、分布式语音照相机、分布式调度启动远程FA(Feature Ability)、跨设备视频播放、分布式新闻客户端、分布式亲子早教系统共9个分布式项目教程。
从Harmony的这几个分布式项目教程中来看,Harmony的分布式与传统Java编程所构建的分布式服务、分布式微服务等后台应用的架构略有不同。
拿笔者曾经编写的《微服务分布式架构基础与实战——基于Spring Boot+Spring Cloud》举例可以看出,分布式微服务架构是指将众多独立运行的Spring Boot项目在注册中心Eureka、ZooKeeper或Consul中进行注册,注册后注册中心会有其他相应服务的地址,另外的Spring Boot微服务项目可以通过注册中心的地址获取到一些服务与资源。例如购物车服务可以通过账号管理服务中心获取用户的账号、密码及头像等相关信息。
而Harmony的分布式,类似这种分布式服务、分布式微服务的架构。例如开发者教程中的分布式游戏手柄项目,该项目将手机屏幕变成手柄的上、下、左、右、A、B键,用户可以通过手机控制电视里游戏角色的动作。当然根据官方描述,Harmony的分布式必须基于同一个网络并且要求设备使用同一个华为账号登录。简而言之,就是电视中的Harmony系统要与手机Harmony系统同时连接在同一个Wi-Fi中,手机作为注册中心,通过Wi-Fi集成范围内所有Harmony设备,并且底层会记录这些设备的地址,方便用户下次直接连接使用。
在过去出现过不少像这种分布式游戏手柄的项目,例如用小米手机控制室内的灯光亮度,用手机控制空调温度的高低。甚至还出现了模块化的智能家居构建,例如对于非智能家居,可以只买灯的智能开关,就可以通过手机间接控制灯的开启和关闭。这样只需要购买一个家居模块即可,而不需要必须有小爱音箱、天猫精灵这种智能家居的中心。
Harmony理想中的世界应该是,在智能家居场景下,通过手机可以控制家中的一切智能设备,甚至在下班回家之前就可以放好洗澡水,并且煮好米饭。
在游戏场景下,Harmony的用户在室内可以通过手机玩电视上的游戏,不需要额外购买手柄,当然这部分游戏暂时只能是基于Harmony和Android编写出来的游戏,暂时无法涉及PC游戏和主机游戏。游戏编程与之前并无不同,例如使用Cocos、Unity、Godot或Unreal等引擎编写的游戏打包成APK(Android Application Package,Android安装包),可以放到Harmony里兼容运行。
在亲子教育场景下,只要在同一个Wi-Fi下,家长可以隔着房间给孩子的错题进行标注,随时看到孩子正在写的题和练习题的作答步骤。
在轻办公场景下,如果手机中的截图需要用平板计算机进行发送,操作会十分复杂,Harmony具有分布式邮件发送的功能,可以同时调用不同设备中的文档或素材,进行跨设备操作,发送数据。
Harmony理想中的世界,是真正意义上万物互联的世界。以前因手机厂商、软件开发商、硬件制造商、用户等多方面协调的原因,万物互联的课题仍然处于萌芽状态。Harmony直接将最复杂的协议、通信、注册、协调等内容集成为接口,日后软件制造商可以更轻易地编写万物互联的软件。在HMS制定好的规则之下,各方面人员与其所在的公司都节省了大量的成本,这就是Harmony理想中的分布式世界。
学习HarmonyOS之前需要先熟悉Java语言与JavaScript语言,最好了解Android基础知识。HarmonyOS示例代码项目的主要编程语言是Java语言与JavaScript语言。示例代码项目在HarmonyOS Developer官网有详细讲解,在此不做赘述。
应用开发的编辑工具为DevEco Studio,它支持Windows和macOS,要求内存为8GB以上、硬盘容量为100GB以上。
设备开发的编辑工具为DevEco Device Tool,支持Windows和Linux,支持图形化操作和命令行操作两种操作方式,支持海思Hi3516、Hi3518、Hi3861等系列开发板。
首先需要通过HarmonyOS Developer官网下载HarmonyOS的开发工具DevEco Studio,其官方网站的环境搭建说明文档十分详细,在此不赘述。
DevEco Studio的安装十分简单,只需要解压缩下载好的压缩包并运行安装程序,之后按步骤安装即可,安装过程中会自动安装 OpenJDK、Node.js、LLVM、Gradle。
OpenJDK作为使用GPL(General Public License,公有公开许可证)的Java平台的实现工具包,为开源版本的JDK(Java Development Kit,Java开发工具包)。
Node.js是基于Chrome V8引擎的JavaScript运行环境,其开源与跨平台的特性,使Node.js在编程业内十分受欢迎。
LLVM和大家所熟知的JVM(Java Virtual Machine,Java虚拟机)不同,该虚拟系统提供了一套中间代码和编译基础设施,并围绕这些中间代码和编译基础设施提供了一套全新的编译策略,优化了编译、连接、运行环境和执行过程等。
Gradle是一款基于Apache Ant和Apache Maven的项目自动化构建开源工具,是一款公有灵活的构建工具,支持Maven、Ivy仓库,支持传递性依赖管理。
DevEco Studio自身基于IntelliJ Platform开源版本进行封装编写,可以理解为它是基于IntelliJ IDEA的社区版进行封装编写出的IDE(Integrated Development Environment,集成开发环境),其快捷键、使用习惯与IntelliJ IDEA无不同。
打开DevEco Studio编辑器,选择File→New→New Project菜单命令,如图1-1所示。
图1-1
选择New Project菜单命令之后的界面如图1-2所示,选择Empty Ability模板。
图1-2
单击Next按钮后,进入配置项目,即可配置该项目的基本参数,其中Language选择Java,如图1-3所示,配置完成后,单击Finish按钮即可进入编写程序的阶段了。
图1-3
初次创建HarmonyOS Developer项目后,需要等待DevEco Studio下载相关依赖并初始化相关参数等,之后项目目录如图1-4所示。
图1-4
HarmonyOS的应用程序(以下简称“应用”)包以App Pack(Application Package)形式发布,它由一个或多个鸿蒙软件安装包(HAP)以及描述每个HAP属性的pack.info组成。HAP是Ability的部署包,HarmonyOS应用代码围绕Ability组件展开。一个HAP是由代码、资源、第三方库及应用配置文件组成的。从图1-4中可以看到项目的文件和目录,部分的释义如下。
● entry:启动模块(主模块),开发者用于编写源代码文件以及开发资源文件的目录。
● entry→.gitignore:用于标识git版本管理需要忽略的文件。
● entry→build.gradle:entry模块的编译配置文件。
● entry→src→main→Java:用于存放Java源代码。
● entry→src→main→resources:用于存放资源文件(字符串、图片、音频等)。
● entry→src→main→config.json:HAP清单文件。
● entry→src→test:存放测试文件的目录。
● entry→src→main→resources→base→element:包括字符串、整数、颜色、样式等资源的JSON文件。每个资源文件均以JSON格式进行保存(如boolean.json—布尔型、color.json—颜色、float.json—浮点型、intarray.json—整型数组、integer.json—整型、pattern.json—样式、plural.json—复数、strarray.json—字符串数组、string.json—字符串)。
● entry→src→main→resources→base→graphic:用于存放XML类型的可绘制资源,如SVG(Scalable Vector Graphics,可缩放矢量图形)文件、Shape基本的几何图形(如矩形、圆形、线等)。
● entry→src→main→resources→base→layout:用于存放XML类型的布局资源。
● entry→src→main→resources→base→media:用于存放媒体文件,如图形、视频、音频等文件(如.png、.gif、.mp3、.mp4等文件)。
● build.gradle:Gradle配置文件,由系统自动生成,一般情况下不需要进行修改。
● entry→libs:应用依赖的第三方代码(如.so、.jar、.bin、.har等二进制文件)。
● local.properties:用于存放本地插件依赖地址。
● entry→build.gradle:该HAP目前的gradle编译配置文件。
Ability是应用所具备能力的抽象,也是应用程序的重要组成部分。一个应用可以具备多种能力,即可以包含多个Ability,HarmonyOS支持应用以Ability为单位进行部署。Ability主要分为FA(Feature Ability)和PA(Particle Ability)两种类型,每种类型为开发者提供了不同的模板,以便实现不同的业务功能。
FA支持Page模板:Page模板是FA唯一支持的模板,用于提供与用户交互的能力。一个Page实例可以包含一组相关页面,每个页面用一个AbilitySlice实例表示。
PA支持Service模板和Data模板:Service模板用于提供后台运行任务的能力,Data模板用于对外部提供统一的数据访问抽象。
HarmonyOS的Ability与Android的Activity类似,在实际应用能力与相应生命周期等概念上无太大区别,都是用来与用户进行交互的应用组件。在Android中,一个应用程序由多个相对松散的Activity组成,一般会指定应用中的某个Activity为主活动,也就是首次启动应用时给用户呈现的Activity。Android应用的主活动需要在清单AndroidManifest.xml中声明,AndroidManifest.xml部分代码如下。
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
而HarmonyOS应用中的entry→src→main→config.json文件的内容主要分为“app”“deviceConfig” “module”3个部分,其中module中的mainAbility参数用于设置HAP的入口Ability,它既可作为整体HAP的入口,也可视作本示例中第一个页面的位置。
HarmonyOS应用初始化时module中的mainAbility参数如下,以此来指定HarmonyOS应用的第一个展示页面(或动作)。
"mainAbility": "com.example.myapplication.MainAbility"
上述Java代码指定了HarmonyOS应用程序的第一个入口页面,其部分代码如下。
public class MainAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(MainAbilitySlice.class.getName());
}
}
Android应用程序的类似功能的Java部分代码如下。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
它们的作用都是初始化应用的第一个页面。HarmonyOS使用Java UI(User Interface,用户界面)框架进行页面编写,主要有两种编写页面的方式,分别是通过XML显式声明UI布局,以及在代码中创建布局。这两种方式创建出的布局没有本质差别。
在通过XML显式声明UI布局之时,可以使用类似Android Studio的图形化编辑方式,在不直接编写代码的情况下编辑页面。
在MainAbility 代码中的Ability归属于Page,Page就是页面的实例,Page可以包含一组(至少需要包含一个)具体的页面;setMainRoute()的作用是设置路由,MainAbilitySlice为具体的页面。
创建HarmonyOS项目之后,项目中自带一个初始化的“你好,世界”页面,通过HarmonyOS模拟器可直接运行。
选择菜单Tools→Device Manager命令,如图1-5所示。
图1-5
启动管理器后需要选择启动哪种模拟器,并且需要登录华为账号,如图1-6所示。
图1-6
登录之后可选择模拟器模拟的手机型号,如图1-7所示。
图1-7
单击Actions下的启动按钮即可启动HarmonyOS模拟器,模拟器效果如图1-8所示。
图1-8
单击右上角的Run 'entry'按钮,如图1-9所示,即可在HarmonyOS模拟器上运行HarmonyOS应用,运行效果如图1-10所示。
图1-9
图1-10
如果因为HarmonyOS版本变动,导致初始化项目后没有提供“你好,世界”页面也无所谓,1.9节将正式编写HarmonyOS的第一个应用。
(1)初步熟悉使用XML显式声明UI布局。
(2)初步熟悉使用Java代码编写页面布局。
(3)初步熟悉页面跳转。
(4)初步熟悉按钮组件。
本节的实战将分别通过XML显式声明UI布局与Java代码编写布局这两种方式编写两个简单的页面,并通过单击按钮跳转到代码创建的页面。
在entry→src→main→resources→base→graphic文件夹下创建文件并命名为background_button.xml,以创建Button的样式,代码如下。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle">
<corners ohos:radius="100"/><!-- 圆角 -->
<solid ohos:color="#007DFF"/><!-- 颜色 -->
</shape>
在entry→src→main→resource→base→layout文件夹下创建文件,并将其命名为main_layout.xml,通常布局类型包括单一方向布局、相对位置布局、精确位置布局,本实战采用相对位置布局DependentLayout,main_layout.xml声明代码如下。
<?xml version="1.0" encoding="utf-8"?>
<DependentLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:background_element="#000000">
<Text
ohos:id="$+id:test"
ohos:width="match_content"
ohos:height="match_content"
ohos:center_in_parent="true"
ohos:text="你好!张方兴! "
ohos:text_color="white"
ohos:text_size="40vp"/>
<Button
ohos:id="$+id:button"
ohos:width="match_content"
ohos:height="match_content"
ohos:text="跳转下一页面"
ohos:text_size="19fp"
ohos:text_color="#FFFFFF"
ohos:top_padding="8vp"
ohos:bottom_padding="8vp"
ohos:right_padding="70vp"
ohos:left_padding="70vp"
ohos:center_in_parent="true"
ohos:below="$id:test"
ohos:margin="10vp"
ohos:background_element="$graphic:background_button"/>
</DependentLayout>
此声明代码中部分内容的释义如下。
● DependentLayout:相对位置布局。
● xmlns:配置XML文件的schma定义。
● ohos:HarmonyOS配置头。
● match_parent:所在布局或组件采用父类容器的高度,如果在XML文件最外层的布局中采用该配置,则会采用屏幕的高度。
● ohos:id:该组件的id,设置后会将该组件自动注册到ResourceTable之中,可在Java代码中调用该组件。
● ohos:height:配置高度。
● ohos:width:配置宽度。
● vp:虚拟像素(Virtual Pixel),HarmonyOS独有的计量单位,是一台设备针对应用而言所具有的虚拟尺寸(区别于屏幕硬件本身的像素单位)。它提供了一种灵活的方式来适应不同屏幕的显示效果。除vp外Android中的dpi(屏幕像素密度)、dp(设备独立像素)、sp(缩放独立像素)也都可以使用。
在编辑声明代码的过程中可通过右侧的Previewer工具查看当前编辑的页面样式,如图1-11所示。也可以将模拟器切换至横屏进行查看,效果如图1-12所示。
图1-11
图1-12
修改com.example.myapplication_01.slice.MainAbilitySlice文件如下。
package com.example.myapplication_01.slice;
import com.example.myapplication_01.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
public class MainAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_main_layout);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
此文件中通过super.setUIContent()设置初始化页面,由于本实战的布局存放在resources→base →layout文件夹下,所以默认被注册在ResourceTable对象内,只需要直接进行调用即可。另外要注意此处需要引用自己项目的ResourceTable,默认情况下会有本项目的ResourceTable和底层自带的ResourceTable,例如此处引用的是com.example.myapplication_01.ResourceTable。
MainAbilitySlice之所以是初次进入应用时展示的页面,是因为在MainAbility类中进行了定义,com.example.myapplication_01.MainAbility代码如下。
package com.example.myapplication_01;
import com.example.myapplication_01.slice.MainAbilitySlice;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
public class MainAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(MainAbilitySlice.class.getName());
}
}
在这段代码中通过setMainRoute()将初始化页面设置为MainAbilitySlice.class,所以MainAbilitySlice是初次进入应用时展示的页面。
MainAbility之所以能够定义初始化页面,是因为它在项目的config.json中进行了定义,config.json在前文有简略描述。
在设置好第一个页面之后,可以通过HarmonyOS模拟器运行应用,得到的效果与图1-11相同。
创建新的类com.example.myapplication_01.slice.MyAbilitySlice,用于使用Java代码编写第二个页面,代码如下。
package com.example.myapplication_01.slice;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.components.DependentLayout.LayoutConfig;
public class MyAbilitySlice extends AbilitySlice{
@Override
public void onStart(Intent intent) {
super.onStart(intent);
// 声明布局
DependentLayout myLayout = new DependentLayout(this);
// 设置布局宽高
myLayout.setWidth(LayoutConfig.MATCH_PARENT);
myLayout.setHeight(LayoutConfig.MATCH_PARENT);
// 设置布局背景为白色
ShapeElement background = new ShapeElement();
background.setRgbColor(new RgbColor(255, 255, 255));
myLayout.setBackground(background);
// 创建一个文本
Text text = new Text(this);
text.setText("Hi 第二个页面");
text.setWidth(LayoutConfig.MATCH_PARENT);
text.setTextSize(100);
text.setTextColor(Color.BLACK);
// 设置文本的布局
DependentLayout.LayoutConfig textConfig = new
DependentLayout.LayoutConfig(LayoutConfig.MATCH_CONTENT,
LayoutConfig.MATCH_CONTENT);
textConfig.addRule(LayoutConfig.CENTER_IN_PARENT);
text.setLayoutConfig(textConfig);
myLayout.addComponent(text);
super.setUIContent(myLayout);
}
}
虽然第一个页面已经展示出了按钮效果,但是该按钮无法正常使用,因为它还没有添加监听器,修改com.example.myapplication_01.slice.MainAbilitySlice的onStart()函数如下。
package com.example.myapplication_01.slice;
import com.example.myapplication_01.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
public class MainAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_main_layout);
//获取页面上的按钮
Button button = (Button) findComponentById(ResourceTable.Id_button);
//给按钮添加监听器,单击按钮跳转至第二个页面
button.setClickedListener(listener -> present(new MyAbilitySlice(), new
Intent()));
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
此时便在第一个页面中获取到了按钮,并且为它添加了单击事件的监听器,一旦发生单击事件便会跳转到MyAbilitySlice实例页面之中。
present( )为SDK(Software Development Kit,软件开发工具包)中的内置函数,只需要直接调用即可。如果出现找不到该函数等相关错误,需要查看一下继承的类是否正确,或者SDK是否被正确设置。
如果要编写有参数的跳转功能,只需要把参数放置在Intent对象之中即可,代码如下。
...
//有参数跳转
Intent intent1 = new Intent();
intent1.setParam("paramKey","paramValue");
present(new MyAbilitySlice(),intent1);
...
启动模拟器,运行应用程序,进入第一个页面,如图1-11所示;单击按钮后进入第二个页面,如图1-13所示。
图1-13
最终项目结构如图1-14所示。
图1-14
HarmonyOS提供了单独的代码调试工具HiLog,HiLog是一个类,其输出需要HiLogLabel的支持。HiLog含有debug、info、warn、error、fatal由小到大的5个输出级别。
HiLogLabel是HiLog的一个入参,通常被设置为静态变量。HiLogLabel的构造方法为public HiLogLabel(int type, int domain, String tag),其释义如下。
● type:用于定义HiLogLabel的类型,如HiLog.debug、HiLog.info、HiLog.warn、HiLog.error、HiLog.fatal、HiLog.LOG_APP。
● domain:用于定义服务域(Service Domain),相似的输出日志使用相似的服务域,取值范围从0x00000到0xFFFFF。前3位通常为子系统名称,后两位通常为模块名称。
● tag:用于定义日志的标签名称。
此时可以更改一下1.9节的com.example.myapplication_01.slice.MainAbilitySlice类,使它可以通过HiLog输出一下相关日志信息。
...
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
...
static final HiLogLabel hiLogLabel = new HiLogLabel(HiLog.LOG_APP,0x00101,
"MainAbilitySliceLog");
@Override
public void onStart(Intent intent) {
super.onStart(intent);
//引入XML布局配置文件
super.setUIContent(ResourceTable.Layout_main_layout);
HiLog.info(hiLogLabel,"张方兴的日志输出");
//获取页面上的按钮
Button button = (Button) findComponentById(ResourceTable.Id_button);
//给按钮添加监听器,单击按钮跳转至第二个页面
button.setClickedListener(listener -> present(new MyAbilitySlice(), new
Intent()));
}
...
代码修改完成后,重新在模拟器上运行程序,在DevEco Studio的左下角选择打开hilog窗口,即可看到输出的相关日志信息,如图1-15所示。
图1-15
HarmonyOS的Debug功能与IntelliJ IDEA无太大区别,只要在行数旁单击即可设置断点,如图1-16所示。
图1-16
设置断点之后,打开模拟器,单击Run 'entry'按钮右侧的Debug 'entry'按钮运行程序即可,如图1-17所示。
图1-17
(1)请简述GMS、AOSP与Android之间的区别。
(2)请简述HMS、Open Harmony与HarmonyOS之间的区别。
(3)请简述Harmony开发的两种方向。
(4)Java代码应该写在哪个目录下?
(5)FA代表什么?
(6)PA代表什么?
(7)setMainRoute()的作用是什么?
(8)在开发Harmony应用时如何进行日志输出?
(9)在开发Harmony应用时如何进行Debug?