前言
上一篇,我们在鸿蒙上写了一个HDF驱动并操作了一下LED硬件,这一篇我们来尝试一下构建一个有简单界面的App,体验一下鸿蒙的前端开发流程。
环境准备
1. 安装DevEco Studio
解压相应的压缩包(文末附下载链接),这里以win10为例,双击deveco-studio-2.0.12.201.exe
指定安装目录
设置可选快捷方式和环境变量
一路下一步即可。
同意用户协议后,就能正常启动了。
2. 更新sdk
在菜单 Setting->HarmonyOS SDK->SDK Platforms
中,选择Js
和Java
,安装新版的SDK
。
同样在SDK Tools
中,选中新版的Previewer
点击Apply
更新
新建项目
点击菜单File->New Project...
,选择智慧屏Smart Vision
,创建一个空模板应用。
填入项目名称MyUiAPP
,点击完成就能创建一个工程了。
遇到 gradle
下载太慢或版本差异的,可以直接在以下网址用工具下载
https://services.gradle.org/distributions/
目录结构
我们先分析一下目录结构,做Android
开发的会倍感亲切。
1. APP
HarmonyOS
的应用软件包以APP Pack(Application Package)
形式发布,它是由一个或多个HAP(HarmonyOS Ability Package)
以及描述每个HAP
属性的pack.info
组成。HAP
是Ability
的部署包,HarmonyOS
应用代码围绕Ability
组件展开。
一个HAP
是由代码、资源、第三方库及应用配置文件组成的模块包,可分为entry
和feature
两种模块类型。
「entry」:应用的主模块。一个APP中,对于同一设备类型必须有且只有一个
entry
类型的HAP
,可独立安装运行。「feature」:应用的动态特性模块。一个
APP
可以包含一个或多个feature
类型的HAP
,也可以不含。只有包含Ability
的HAP
才能够独立运行。
2. Ability
Ability是应用所具备的能力的抽象,一个应用可以包含一个或多个Ability
。Ability
分为两种类型:FA(Feature Ability)
和PA(Particle Ability)
。FA/PA
是应用的基本组成单元,能够实现特定的业务功能。FA
有UI
界面,而PA
无UI
界面。
3. 资源文件
应用的资源文件(字符串、图片、音频等)统一存放于resources
目录下,便于开发者使用和维护。resources
目录包括两大类目录,一类为base
目录与限定词目录,另一类为rawfile
目录。
4. 配置文件
配置文件(config.json)
是应用的Ability
信息,用于声明应用的Ability
,以及应用所需权限等信息。
应用的全局配置信息,包含应用的包名、生产厂商、版本号等基本信息。
应用在具体设备上的配置信息,包含应用的备份恢复、网络安全等能力。
HAP
包的配置信息,包含每个Ability
必须定义的基本属性(如包名、类名、类型以及Ability
提供的能力),以及应用访问系统或其他应用受保护部分所需的权限等。
5. JS UI 框架
JS UI
框架是一种跨设备的高性能UI
开发框架,支持声明式编程和跨设备多态UI
。
声明式编程
JS UI
框架采用类HTML
和CSS
声明式编程语言作为页面布局和页面样式的开发语言,页面业务逻辑则支持ECMAScript
规范的JavaScript
语言。JS UI
框架提供的声明式编程,可以让开发者避免编写UI
状态切换的代码,视图配置信息更加直观。跨设备
开发框架架构上支持
UI
跨设备显示能力,运行时自动映射到不同设备类型,开发者无感知,降低开发者多设备适配成本。高性能
开发框架包含了许多核心的控件,如列表、图片和各类容器组件等,针对声明式语法进行了渲染流程的优化。
JS UI
框架包括应用层(Application)
、前端框架层(Framework)
、引擎层(Engine)
和平台适配层(Porting Layer)
。
空气质量监测 UI
1. 创建首页面
空气质量监测App包含两个界面(Page)
,工程创建完成后会生成一个名为index
的Page
,可以作为首页。
2. 创建详情页
在pages
目录按右键,弹出的菜单中选择New->JS Page
。
输入页面名称detail
,
详情页创建完成后应用工程目录如下图所示,每个Page
包括三个文件:布局文件hml
、样式文件css
、业务逻辑代码js
。
3. 开发首页
应用首页主要展示城市的空气质量概况。首页总共有两屏(可以根据需求设置多屏),每屏显示一个城市的空气质量信息:主要包括AQI指数、城市名称、污染物指数、更新时间和信息来源等数据。
3.1 创建根节点
修改entry/src/main/js/default/pages/index/index.hml
,加入根节点div
:
-
<div class=
"container">
-
</div>
3.2 创建样式
修改entry/src/main/js/default/pages/index/index.css
-
.container {
-
flex-direction: column;
-
height:
480px;
-
width:
960px;
-
}
3.3 添加标题栏
标题栏包括一个退出按钮和一个标题,两个控件是横向排列
-
<div class=
"container">
-
<div class=
"header" onclick=
"exitApp">
-
<image class=
"back" src=
"common/ic_back.png"></image>
-
<text class=
"title">
-
空气质量
-
</text>
-
</div>
-
</div>
注意,这里要先导入common/ic_back.png
图标资源。
3.4 添加标题栏样式
修改entry/src/main/js/default/pages/detail/detail.css
,添加以下代码,设置组件的高度、边距、颜色等属性。
-
.header {
-
width:
960px;
-
height:
72px;
-
}
-
.back {
-
width:
36px;
-
height:
36px;
-
margin-left:
39px;
-
margin-top:
23px;
-
}
-
.title {
-
width:
296px;
-
height:
40px;
-
margin-top:
20px;
-
margin-left:
21px;
-
color: #e6e6e6;
-
}
3.5 添加退出事件
onclick="exitApp"
设置了div
组件的click
事件,当在标题栏上触发点击事件时,就会执行函数exitApp
,该函数位于index.js
文件中,代码如下:
-
exitApp() {
-
console.log(
'start exit');
-
app.terminate();
-
console.log(
'end exit');
-
}
app.terminate()
函数实现了程序退出功能;在使用该函数前,需要引入app
模块,在index.js
文件的最上方写如下代码:
import app from '@system.app'
在 Previewer 窗口中,可以预览界面效果
3.6 滑动组件
实现城市空气质量信息的多屏左右滑动,需要使用“swiper”
组件。
在根节点中添加一个子节点swiper
, 修改index.hml
-
<swiper class=
"swiper" index=
"{{swiperPage}}" duration=
"500" onchange=
"swiperChange">
-
-
</swiper>
添加样式,修改index.css
-
.swiper {
-
height:
385px;
-
width:
960px;
-
}
绑定swiperPage
变量,swiperChange
事件,修改index.js
-
//引入router模块,用户页面跳转
-
import router from
'@system.router'
-
import app from
'@system.app'
-
-
export
default {
-
//定义参数
-
data: {
-
//默认是第一页
-
swiperPage:
0
-
},
-
onInit () {
-
},
-
exitApp(){
-
console.log(
'start exit');
-
app.terminate();
-
console.log(
'end exit');
-
},
-
//swiper滑动回调事件,保存当前swiper的index值,每次滑动都会将index值保存在swiperPage变量中
-
swiperChange (e) {
-
this.swiperPage = e.index;
-
}
-
}
在swiper
中添加两个子组件stack
(绝对布局),每个stack
组件内分别添加text、image、progress
等组件来显示对应的信息。
-
<div class=
"container">
-
<div class=
"header" onclick=
"exitApp">
-
<image class=
"back" src=
"common/ic_back.png"></image>
-
<text class=
"title">
-
空气质量
-
</text>
-
</div>
-
<swiper class=
"swiper" index=
"{{swiperPage}}" duration=
"500" onchange=
"swiperChange">
-
<!--第一屏-->
-
<stack class=
"swiper">
-
<!--空气质量-->
-
<text class=
"airquality" style=
"color:{{textColor1}};">{{airData[
0].airQuality}}</text>
-
<!--城市名称-->
-
<text class=
"location-text">{{airData[
0].location}}</text>
-
<!--进度条-->
-
<progress
-
class=
"circleProgress"
-
style=
"color:{{textColor1}};background-Color:{{bgColor1}};"
-
type=
"arc"
-
onclick=
"openDetail"
-
percent=
"{{percent1}}">
-
</progress>
-
<!--云朵图片-->
-
<image class=
"image" src=
"{{src1}}"></image>
-
<!--AQI数值-->
-
<text class=
"pm25-value">{{ airData[
0].detailData }}</text>
-
<text class=
"pm25-name">AQI</text>
-
<!--空气指标详细信息-->
-
<div class=
"detail">
-
<div class=
"text-wrapper">
-
<text class=
"gas-name">
-
CO
-
</text>
-
<text class=
"gas-value">
-
100
-
</text>
-
</div>
-
<div class=
"text-wrapper">
-
<text class=
"gas-name">
-
NO2
-
</text>
-
<text class=
"gas-value">
-
90
-
</text>
-
</div>
-
<div class=
"text-wrapper">
-
<text class=
"gas-name">
-
PM10
-
</text>
-
<text class=
"gas-value">
-
120
-
</text>
-
</div>
-
<div class=
"text-wrapper">
-
<text class=
"gas-name">
-
PM2
.5
-
</text>
-
<text class=
"gas-value">
-
40
-
</text>
-
</div>
-
<div class=
"text-wrapper">
-
<text class=
"gas-name">
-
SO2
-
</text>
-
<text class=
"gas-value">
-
150
-
</text>
-
</div>
-
<input class=
"btn"
type=
"button" onclick=
"openDetail" value=
"历史记录"></input>
-
</div>
-
<!--更新时间和网站等信息-->
-
<div class=
"footer">
-
<text class=
"update-time">
-
更新时间:
10:
38
-
</text>
-
<text class=
"info-source">
-
信息来源: tianqi.com
-
</text>
-
</div>
-
</stack>
-
-
<!--第二屏-->
-
<stack class=
"swiper">
-
<text class=
"airquality" style=
"color: {{textColor2}};">{{airData[
1].airQuality}}</text>
-
<text class=
"location-text">{{airData[
1].location}}</text>
-
<progress class=
"circle-progress" style=
"color: {{textColor2}};background-Color: {{bgColor2}};"
type=
"arc"
-
percent=
"{{percent2}}"></progress>
-
<image class=
"image" src=
"{{src2}}"></image>
-
<text class=
"aqi-value">{{airData[
1].detailData}}</text>
-
<text class=
"aqi">
-
AQI
-
</text>
-
<div class=
"detail">
-
<div class=
"text-wrapper">
-
<text class=
"gas-name">
-
CO
-
</text>
-
<text class=
"gas-value">
-
10
-
</text>
-
</div>
-
<div class=
"text-wrapper">
-
<text class=
"gas-name">
-
NO2
-
</text>
-
<text class=
"gas-value">
-
50
-
</text>
-
</div>
-
<div class=
"text-wrapper">
-
<text class=
"gas-name">
-
PM10
-
</text>
-
<text class=
"gas-value">
-
60
-
</text>
-
</div>
-
<div class=
"text-wrapper">
-
<text class=
"gas-name">
-
PM2
.5
-
</text>
-
<text class=
"gas-value">
-
40
-
</text>
-
</div>
-
<div class=
"text-wrapper">
-
<text class=
"gas-name">
-
SO2
-
</text>
-
<text class=
"gas-value">
-
150
-
</text>
-
</div>
-
<input class=
"btn"
type=
"button" onclick=
"openDetail" value=
"历史记录"></input>
-
</div>
-
<div class=
"footer">
-
<text class=
"update-time">
-
更新时间:
10:
38
-
</text>
-
<text class=
"info-source">
-
信息来源: tianqi.com
-
</text>
-
</div>
-
</stack>
-
</swiper>
-
</div>
3.7 页面位置指示器
添加页面位置指示器:由于当前swiper
不支持设置indicator
,需要开发者自己来实现该效果。在根节点中添加一个子组件div
,并设置相应样式;然后在该div
中添加两个子组件div
,设置两个div
的border-radius
,并在swiper
滑动事件中动态改变对应div
的背景色来实现该效果。
修改index.hml
,在swiper
组件后加入以下代码:
-
<div class=
"images">
-
<div class=
"circle-div" style=
"background-color: {{iconcheckedColor}};"></div>
-
<div class=
"circle-div" style=
"background-color: {{iconUncheckedColor}};margin-left: 36px;"></div>
-
</div>
3.8 新增文字样式
修改 index.css
-
.aqi-value {
-
text-align: center;
-
font-size:
65px;
-
color: #f0ffff;
-
width:
156px;
-
height:
92px;
-
top:
134px;
-
left:
210px;
-
}
-
.aqi {
-
text-align: center;
-
color: #a2c4a2;
-
width:
156px;
-
height:
45px;
-
top:
90px;
-
left:
210px;
-
}
-
.airquality {
-
top:
222px;
-
text-align: center;
-
width:
156px;
-
height:
45px;
-
left:
210px;
-
}
-
.image {
-
top:
285px;
-
left:
274px;
-
width:
32px;
-
height:
32px;
-
}
-
.location-text {
-
text-align: center;
-
color: #ffffff;
-
width:
250px;
-
height:
52px;
-
font-size:
40px;
-
left:
380px;
-
top:
16px;
-
}
-
.container {
-
flex-direction: column;
-
height:
480px;
-
width:
960px;
-
}
-
.circle-progress {
-
center-x:
128px;
-
center-y:
128px;
-
radius:
128px;
-
startAngle:
198;
-
totalAngle:
320;
-
strokeWidth:
24px;
-
width:
256px;
-
height:
256px;
-
left:
160px;
-
top:
58px;
-
}
-
.detail {
-
width:
256px;
-
height:
265px;
-
left:
544px;
-
top:
58px;
-
flex-direction: column;
-
}
-
.text-wrapper {
-
width:
256px;
-
height:
35px;
-
margin-top:
6px;
-
}
-
.gas-name {
-
width:
128px;
-
height:
35px;
-
text-align: left;
-
}
-
.gas-value {
-
width:
128px;
-
height:
35px;
-
text-align: right;
-
}
-
.btn {
-
width:
180px;
-
height:
50px;
-
margin-top:
6px;
-
margin-left:
38px;
-
background-color: #
1a1a1a;
-
color: #
1085CE;
-
}
-
.footer {
-
top:
326px;
-
width:
960px;
-
height:
28px;
-
}
-
.header {
-
width:
960px;
-
height:
72px;
-
}
-
.back {
-
width:
36px;
-
height:
36px;
-
margin-left:
39px;
-
margin-top:
23px;
-
}
-
.title {
-
width:
296px;
-
height:
40px;
-
margin-top:
20px;
-
margin-left:
21px;
-
color: #e6e6e6;
-
}
-
.swiper {
-
height:
385px;
-
width:
960px;
-
}
-
.images {
-
width:
60px;
-
height:
15px;
-
margin-left:
450px;
-
}
-
.update-time {
-
width:
480px;
-
height:
28px;
-
font-size:
20px;
-
color: #A9A9A9;
-
text-align: right;
-
}
-
.info-source {
-
width:
450px;
-
height:
28px;
-
font-size:
20px;
-
color: #A9A9A9;
-
text-align: left;
-
margin-left:
24px;
-
}
-
.circle-div {
-
width:
12px;
-
height:
12px;
-
border-radius:
6px;
-
}
3.9 实现页面逻辑
修改index.js
,绑定页面数据data
。初始化时,根据不同的数值显示不同的字体和图片onInit
。实现页面跳转openDetail
,将当前页面索引传递给detail
页面。滑动触发后swiperChange
改变指示位置。
-
//引入router模块,用户页面跳转
-
import router from
'@system.router'
-
import app from
'@system.app'
-
-
export
default {
-
//定义参数
-
data: {
-
//页面绑定数据
-
textColor1:
"#00ff00",
-
textColor2:
"#00ff00",
-
bgColor1:
"#669966",
-
bgColor2:
"#669966",
-
//默认是第一页
-
swiperPage:
0,
-
percent1:
10,
-
percent2:
90,
-
iconUncheckedColor:
'#262626',
-
iconcheckedColor:
'#ffffff',
-
iconcheckedBR:
'6px',
-
src1:
"common/cloud_green.png",
-
src2:
"common/cloud_green.png",
-
airData: [
-
{
-
location:
"HangZhou",
-
airQuality:
"Good",
-
detailData:
10
-
},
-
{
-
location:
"ShangHai",
-
airQuality:
"Unhealth",
-
detailData:
90
-
}
-
]
-
},
-
onInit () {
-
//根据数值的不同,设置不同的字体、背景颜色和图片
-
if(this.airData[
0].detailData >
100){
-
this.src1 =
'common/cloud_red.png';
-
this.textColor1 =
'#ff0000';
-
this.bgColor1 =
'#9d7462';
-
}
else
if(
50 < this.airData[
0].detailData && this.airData[
0].detailData <=
100){
-
this.src1 =
'common/cloud_yellow.png';
-
this.textColor1 =
'#ecf19a';
-
this.bgColor1 =
'#9d9d62';
-
}
-
if(this.airData[
1].detailData >
100){
-
this.src2 =
'common/cloud_red.png';
-
this.textColor2 =
'#ff0000';
-
this.bgColor2 =
'#9d7462';
-
}
else
if(
50 < this.airData[
1].detailData && this.airData[
1].detailData <=
100){
-
this.src2 =
'common/cloud_yellow.png';
-
this.textColor2 =
'#ecf19a';
-
this.bgColor2 =
'#9d9d62';
-
}
-
if(this.selectedCityIndex){
-
this.swiperPage = this.selectedCityIndex;
-
if(this.swiperPage ==
0){
-
this.iconcheckedColor =
'#ffffff';
-
this.iconUncheckedColor =
'#262626';
-
}
else{
-
this.iconcheckedColor =
'#262626';
-
this.iconUncheckedColor =
'#ffffff';
-
}
-
}
-
},
-
//跳转到详情页面
-
openDetail () {
-
router.replace({
-
uri:
'pages/detail/detail',
-
params: {selectedCityIndex:this.swiperPage}
-
});
-
},
-
//退出应用
-
exitApp(){
-
console.log(
'start exit');
-
app.terminate();
-
console.log(
'end exit');
-
},
-
//swiper滑动回调事件,保存当前swiper的index值,每次滑动都会将index值保存在swiperPage变量中
-
swiperChange (e) {
-
this.swiperPage = e.index;
-
if(e.index ==
0){
-
this.iconcheckedColor =
'#ffffff';
-
this.iconUncheckedColor =
'#262626';
-
}
else{
-
this.iconcheckedColor =
'#262626';
-
this.iconUncheckedColor =
'#ffffff';
-
}
-
}
-
}
预览效果如下:
4. 开发详情页
详情页以图表的形式展示一周内空气质量指标值。本页面由两部分组成:标题栏和图表栏;在图表栏,考虑显示效果,我们使用多个div
替代chart
组件来实现图表功能。
4.1 添加标题栏
修改 entry/src/main/js/default/pages/detail/detail.hml
-
<div class=
"container">
-
<div class=
"header" onclick=
"backMain">
-
<image class=
"back" src=
"common/ic_back.png"></image>
-
<text class=
"title">
-
历史记录
-
</text>
-
</div>
-
<list class=
"chart-list">
-
</list>
-
</div>
4.2 添加图表栏
添加城市位置到list-item-title
,图表到list-item-chart
-
<list class=
"chart-list">
-
<list-item class=
"list-item-title">
-
<text class=
"location">{{location}}</text>
-
</list-item>
-
<list-item class=
"list-item-chart">
-
</list-item>
-
</list>
4.3 添加图表
-
<div class=
"chart-wrapper" style=
"margin-left: 128px;">
-
<text class=
"gas-name">CO</text>
-
<div class=
"chart">
-
<div class=
"chart-item" style=
"height: 78px;background-color: #00ff00;"></div>
-
<div class=
"chart-item" style=
"height: 52px;background-color: #00ff00;"></div>
-
<div class=
"chart-item" style=
"height: 155px;background-color: #ff0000;"></div>
-
<div class=
"chart-item" style=
"height: 134px;background-color: #ff0000;"></div>
-
<div class=
"chart-item" style=
"height: 98px;background-color: #FF7500;"></div>
-
<div class=
"chart-item" style=
"height: 88px;background-color: #FF7500;"></div>
-
<div class=
"chart-item" style=
"height: 144px;background-color: #ff0000;"></div>
-
</div>
-
<div class=
"white-line"></div>
-
<div class=
"week"></div>
-
</div>
4.4 添加样式
-
.location {
-
text-align: center;
-
color: #ffffff;
-
width:
960px;
-
height:
52px;
-
font-size:
40px;
-
}
-
.container {
-
height:
480px;
-
width:
960px;
-
flex-direction: column;
-
}
-
-
.header {
-
width:
960px;
-
height:
72px;
-
}
-
-
.back {
-
width:
36px;
-
height:
36px;
-
margin-left:
39px;
-
margin-top:
23px;
-
}
-
-
.title {
-
width:
296px;
-
height:
40px;
-
margin-top:
20px;
-
margin-left:
21px;
-
color: #e6e6e6;
-
}
-
-
.chart-list {
-
width:
960px;
-
height:
408px;
-
}
-
-
.list-item-title {
-
width:
960px;
-
height:
52px;
-
}
-
-
.list-item-chart {
-
width:
960px;
-
height:
280px;
-
}
-
-
.chart-wrapper {
-
width:
308px;
-
height:
256px;
-
flex-direction: column;
-
}
-
-
.gas-name {
-
width:
308px;
-
height:
35px;
-
text-align: left;
-
}
-
-
.chart {
-
width:
308px;
-
height:
155px;
-
margin-top:
10px;
-
justify-content: flex-start;
-
align-items: flex-end;
-
}
-
-
.chart-item {
-
width:
24px;
-
margin-left:
18px;
-
border-radius:
3px;
-
}
-
-
.white-line {
-
width:
308px;
-
height:
2px;
-
background-color: #ffffff;
-
margin-top:
22px;
-
}
-
-
.week {
-
width:
308px;
-
height:
17px;
-
margin-top:
6px;
-
border-color: #ffffff;
-
border-radius:
2px;
-
margin-top:
6px;
-
}
-
-
.day {
-
width:
26px;
-
height:
17px;
-
font-size:
10px;
-
margin-left:
16px;
-
text-align: center;
-
}
4.5 实现页面跳转
其中onclick="backMain"
为返回主页事件,根据传递的页面索引,显示不同的位置数据,detail.js
中的代码实现如下:
-
import router from
'@system.router'
-
-
export
default {
-
data: {
-
location:
''
-
},
-
onInit() {
-
if (this.selectedCityIndex ===
0) {
-
this.location =
'杭州';
-
}
else {
-
this.location =
'上海';
-
}
-
},
-
backMain() {
-
router.replace({
-
uri:
'pages/index/index',
-
params: {
-
selectedCityIndex: this.selectedCityIndex
-
}
-
});
-
}
-
}
5. 模拟器调试
菜单Tools->HVD Manager
,可以打开云端的模拟器
注册华为开发者账号,授权登录后
就能看到模拟器列表了,相比beta
版只有Phone
、TV
和Wearable
三种,增加了不少的设备。
可惜还没有可用于smartVision
设备的模拟器,现阶段我们还只能烧录到设备中调试,总体上"富鸿蒙"的进度比较快,期待一波更新。
6. 编译打包
若开发手机端的App
,则需要申请证书,对应用程序进行签名。这样才能发布到应用市场,才被允许安装到真机上运行。
IPCamera
应用「暂时不支持签名模式」,所以需要将应用发布为未签名的应用安装包。
菜单Build->Buildo APP(s)/Hap(s)->Build Release Hap(s)
,生成Hap
文件。
输出文件为 build/outputs/hap/release/smartVision/entry-release-smartVision-unsigned.hap
,改名为MyUiApp.hap
便于安装。
7. 通过sdcard安装
7.1 复制安装包和工具
将IDE编译的未签名应用安装包和安装工具(Z:\openharmony\out\my_hi3516dv300\dev_tools
)放在sdcard
中,将sdcard
插入开发板卡槽。
7.2 禁用签名校验
应用安装默认要校验签名,需要执行以下命令,关闭签名校验。
./sdcard/dev_tools/bin/bm set -s disable
7.3 安装应用
./sdcard/dev_tools/bin/bm install -p /sdcard/MyUiApp.hap
8. 通过NFS安装
每次插拔sdcard
还是蛮不方便的,这里我们安装一个NFS
服务器,让鸿蒙系统能直接访问Win10
的目录,后续安装调试就会方便很多。
8.1 安装NFS服务器
我们先安装一个haneWIN NFS服务器
, 双击文末网盘里的nfs1169.exe
,一路下一步即可。
8.2 配置目录参数
编辑输出表文件,定义传输目录
-
# exports example
-
-
# C:\ftp -
range
192.168
.1
.1
192.168
.1
.10
-
# c:\public -public -readonly
-
# c:\tools -readonly
192.168
.1
.4
-
-
D:\PycharmProjects\aiLearn\Harmony\tftp -public -name:nfs
8.3 重启服务
右键管理员权限,重启所有服务,让配置生效。
8.4 设置防火墙
防火墙设置111、1058、2049
这些端口的TCP
和UDP
,入站规则放行。
8.5 鸿蒙上挂载目录
主电脑的ip
地址为192.168.1.57
,NFS
服务的别名为nfs
,对应的目录为D:\PycharmProjects\aiLearn\Harmony\tftp
-
mkdir nfs
-
mount
192.168
.1
.57:/nfs /nfs nfs
挂载到鸿蒙的刚新建的 /nfs
目录下,我们可以复制安装包和安装工具
8.6 安装应用
-
cd nfs
-
./dev_tools/bin/bm install -p MyUiApp.hap
前面做了这么多的铺垫,后续开发只要复制hap
安装包,直接一条命令安装即可,非常方便。
运行程序
安装完成后,点击桌面上的MyUiApp
就能看见界面效果了。
Js UI框架
对开发者还是比较友好的,有小程序或快应用的开发经验,上手应该都比较顺滑。
不过HarmonyOS Device
的支持库精简的非常严重,例如网络访问的@system.request
和@system.fetch
都不可用,这些功能在“富鸿蒙”的设备上开发就会比较方便。
资料下载
本期相关文件资料,可在公众号“深度觉醒”,后台回复:“ohos06”,获取下载链接。
下一篇
本期主要介绍了一下JS框架下的界面开发,
下一篇我们将尝试熟悉更多的设备能力,
并打通从框架用户态到驱动内核态之间的联系,
敬请期待...
往期推荐
转载:https://blog.csdn.net/weixin_47479625/article/details/112343440