1# 时钟应用开发指导<a name="ZH-CN_TOPIC_0000001115417926"></a> 2 3- [概述](#section11522349121115) 4- [开发准备](#section6592121861218) 5- [开发步骤](#section19901741111312) 6- [签名打包](#section10601181101516) 7- [真机运行](#section092721731511) 8- [常见问题](#section1122413460153) 9 - [hdc\_std连接不到设备](#section1922725151614) 10 - [hdc\_std运行不了](#section15657547131615) 11 12 13## 概述<a name="section11522349121115"></a> 14 15本文将介绍如何快速搭建基于OpenHarmony标准系统(Hi3516DV300开发板)的应用开发环境,并基于一个时钟APP示例逐步展示应用的创建、开发、调试和安装等流程。示例代码可以通过[本链接](https://gitee.com/openharmony/app_samples/tree/master/common/Clock)获取。 16 17时钟App是一款显示实时时间的应用,显示效果如下图所示: 18 19**图 1** 时钟应用显示效果图<a name="fig7763172132019"></a> 20 21 22 23 24## 开发准备<a name="section6592121861218"></a> 25 26首先需要下载和配置DevEco Studio,具体操作请参考[DevEco Studio 使用指南](../../application-dev/quick-start/DevEco-Studio(OpenHarmony)使用指南.md)。 27 28## 开发步骤<a name="section19901741111312"></a> 29 30应用的功能是通过表盘和数字显示实时时间。 31 32从[显示效果图](device-clock-guide.md#fig7763172132019)分析可知,页面由两个部分组成: 33 34- 表盘栏:主要展示一个动态的钟表,且钟表指针能准确转动。 35- 数字时间栏:主要以数字形式显示当前时间。 36 37综上,我们可搭建一个纵向两行排列的弹性页面布局来实现界面的功能。具体开发步骤如下: 38 391. 在hml文件中添加一个根节点div,注意每个hml文件中有且只能有一个根节点,代码如下: 40 41 ``` 42 <div class="container"> 43 </div> 44 ``` 45 46 class="container"表示组件使用的样式,container是index.css文件中的一个样式类,代码如下: 47 48 ``` 49 .container { 50 flex-direction: column; 51 justify-content: center; 52 align-items: center; 53 width: 100%; 54 height: 100%; 55 } 56 ``` 57 58 在这个样式类中,我们分别设置了根组件div的高度和宽度(注意在应用的开发过程中,除部分组件(text)外必须显式指定组件的高度和宽度,否则可能无法显示)、并将flex-direction属性设置为column,该属性表示div的子组件是垂直方向从上到下排列;这样就可以实现本节开头所说的纵向两行排列的弹性页面布局。 59 602. 实现时钟转动,需要使用“stack”组件。“stack”组件的功能是堆叠容器,子组件按照顺序依次入栈,后一个子组件覆盖前一个子组件。 61 62 在根组件下添加一个stack容器,代码片段如下: 63 64 ``` 65 <div class="container"> 66 <stack class="stack"> 67 <image src="/common/clock_bg.png" class="clock-bg"></image> <!--设置表盘图片--> 68 <image src="/common/hour_hand.png" class="clock-hand" 69 style="transform : rotate({{ hour * 30 + minute / 2 }}deg);"></image> <!--设置时钟图片,(hour * 30)一小时旋转30度,(minute / 2)时钟每分钟旋转的角度--> 70 <image src="/common/minute_hand.png" class="clock-hand" 71 style="transform : rotate({{ minute * 6 + second / 10 }}deg);"></image> <!--设置分钟图片,(minute * 6)一分钟旋转6度,(second / 10)分钟每秒钟旋转的角度--> 72 <image src="/common/second_hand.png" class="clock-hand" 73 style="transform : rotate({{ second * 6 }}deg);"></image> <!--设置秒钟图片,(second * 6)一秒旋转6度--> 74 </stack> 75 </div> 76 ``` 77 78 style="transform : rotate\(\{\{ second \* 6 \}\}deg\) 这类代码用来设置组件的旋转事件。其中transform是设置动画平移/旋转/缩放的属性,rotate是旋转动画属性,支持设置x轴和y轴两个维度的选中参数。 79 80 在css文件中设置"stack"组件样式的高度、宽度、位置等属性,代码如下: 81 82 ``` 83 .stack { 84 flex-direction: column; 85 justify-content: center; 86 align-items: center; 87 width: 100%; 88 height: 50%; 89 } 90 ``` 91 92 在css文件中设置"clock-bg"组件样式的高度、宽度等属性,代码如下: 93 94 ``` 95 .clock-bg { 96 width: 80%; 97 height: 80%; 98 object-fit: scale-down; 99 } 100 ``` 101 102 在css文件中设置"clock-hand"组件为时针、分针和秒针的高度、宽度等属性,代码如下: 103 104 ``` 105 .clock-hand { 106 width: 25%; 107 height: 65%; 108 object-fit: contain; 109 } 110 ``` 111 112 index.js中会有一个定时器实时刷新时分秒变量,从而触发时间界面自动更新。对应的js代码如下: 113 114 ``` 115 export default { 116 timer: undefined, 117 //定义参数 118 data: { 119 hour: 0, //定义小时 120 minute: 0, //定义分钟 121 second: 0 //定义秒 122 }, 123 onInit () { 124 this.updateTime(); 125 this.timer = setInterval(this.updateTime, 1000)//设置1s的定时器 126 }, 127 updateTime: function () { 128 var nowTime = new Date() 129 this.hour = nowTime.getHours() 130 this.minute = nowTime.getMinutes() 131 this.second = nowTime.getSeconds() 132 if (this.hour < 10) { 133 this.hour = '0' + this.hour 134 } 135 if (this.minute < 10) { 136 this.minute = '0' + this.minute 137 } 138 if (this.second < 10) { 139 this.second = '0' + this.second 140 } 141 }, 142 } 143 ``` 144 1453. 显示数字时间,在钟表下面以数字形式显示当前时间。在根布局内末尾加上text组件,页面结构如下: 146 147 ``` 148 <text class="digit-clock"> {{ hour }}:{{ minute }}:{{ second }}</text> 149 ``` 150 151 class="digit-clock"设置了组件的高度和宽度以及字体大小,其代码如下: 152 153 ``` 154 .digit-clock { 155 font-size: 58px; 156 width: 100%; 157 margin-top: 0px; 158 text-align: center; 159 } 160 ``` 161 1624. 所有组件设置样式、动画效果和数据动态绑定,完整代码如下所示: 163 - **index.hml文件** 164 165 ``` 166 <div class="container"> 167 <stack class="stack"> 168 <image src="/common/clock_bg.png" class="clock-bg"></image> 169 <image src="/common/hour_hand.png" class="clock-hand" 170 style="transform : rotate({{ hour * 30 + minute / 2 }}deg);"></image> 171 <image src="/common/minute_hand.png" class="clock-hand" 172 style="transform : rotate({{ minute * 6 + second / 10 }}deg);"></image> 173 <image src="/common/second_hand.png" class="clock-hand" 174 style="transform : rotate({{ second * 6 }}deg);"></image> 175 </stack> 176 <text class="digit-clock">{{ hour }}:{{ minute }}:{{ second }}</text> 177 </div> 178 ``` 179 180 - **index.css文件** 181 182 ``` 183 .container { 184 flex-direction: column; 185 justify-content: center; 186 align-items: center; 187 width: 100%; 188 height: 100%; 189 } 190 191 .stack { 192 flex-direction: column; 193 justify-content: center; 194 align-items: center; 195 width: 100%; 196 height: 50%; 197 } 198 199 .digit-clock { 200 font-size: 58px; 201 width: 100%; 202 margin-top: 0px; 203 text-align: center; 204 } 205 206 .clock-bg { 207 width: 80%; 208 height: 80%; 209 object-fit: scale-down; 210 } 211 212 .clock-hand { 213 width: 25%; 214 height: 65%; 215 object-fit: contain; 216 } 217 ``` 218 219 - **index.js:** 220 221 js文件主要用于实现App应用的逻辑交互。在本页面js文件中,需要实现如下功能:定时获取系统时间。 222 223 ``` 224 export default { 225 timer: undefined, 226 data: { 227 hour: 0, 228 minute: 0, 229 second: 0 230 }, 231 onInit() { 232 this.updateTime() 233 this.timer = setInterval(this.updateTime, 1000) 234 }, 235 updateTime: function () { 236 var nowTime = new Date() 237 this.hour = nowTime.getHours() 238 this.minute = nowTime.getMinutes() 239 this.second = nowTime.getSeconds() 240 if (this.hour < 10) { 241 this.hour = '0' + this.hour 242 } 243 if (this.minute < 10) { 244 this.minute = '0' + this.minute 245 } 246 if (this.second < 10) { 247 this.second = '0' + this.second 248 } 249 }, 250 onDestroy() { 251 clearInterval(this.timer); 252 } 253 } 254 ``` 255 256 257 258## 签名打包<a name="section10601181101516"></a> 259 260代码编写完成后,在真机设备上运行应用,需要先对应用进行签名,然后再进行打包,具体操作请参考[签名打包指导](../../application-dev/quick-start/配置OpenHarmony应用签名信息.md)。 261 262## 真机运行<a name="section092721731511"></a> 263 264应用签名打包后即可安装到开发板。安装应用前需要先完成[DevEco Device Tool的安装配置](https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905),然后将OpenHarmony系统烧录到开发板并运行。编译烧录、运行镜像的基本操作请参考快速入门手册:[标准系统Hi3516快速入门](../quick-start/quickstart-standard-overview.md)。完成镜像运行,系统正常启动后,执行如下步骤安装或卸载应用。 265 2661. 从开发者工具代码仓路径中获取hdc客户端。 267 268 ``` 269 developtools/hdc_standard/prebuilt/windows/hdc_std.exe 270 ``` 271 272 修改名称为hdc.exe,并将工具路径加入系统环境path变量中。 273 2742. 启动cmd命令窗口,执行以下命令,推送hap应用包到设备目录下并安装。 275 276 ``` 277 hdc smode 278 hdc target mount 279 hdc file send clock.hap /data/clock.hap 280 hdc shell chmod 666 /data/clock.hap 281 hdc shell bm install -p /data/clock.hap 282 ``` 283 2843. 启动应用。执行以下命令,其中ohos.samples.clock为应用包名,MainAbility为应用启动的Ability。 285 286 ``` 287 hdc shell aa start -d 123 -a ohos.samples.clock.MainAbility -b ohos.samples.clock 288 ``` 289 2904. 卸载应用(可选)。执行以下命令,其中ohos.samples.clock为应用包名。 291 292 ``` 293 hdc shell bm uninstall -n ohos.samples.clock 294 ``` 295 296 297## 常见问题<a name="section1122413460153"></a> 298 299### hdc\_std连接不到设备<a name="section1922725151614"></a> 300 301- **现象描述** 302 303 执行 "hdc\_std list targets"命令后结果为:\[Empty\] 304 305- **可能原因和解决方法** 306 1. 设备没有被识别: 307 308 在设备管理器中查看是否有hdc设备,在通用串行总线设备中会有“HDC Device”信息。如果没有,hdc无法连接。此时需要插拔设备,或者烧写最新的镜像。 309 310 2. hdc\_std工作异常: 311 312 可以执行"hdc kill"或者"hdc start -r"杀掉hdc服务或者重启hdc服务,然后再执行hdc list targets查看是否已经可以获取设备信息。 313 314 3. hdc\_std与设备不匹配: 315 316 如果设备烧写的是最新镜像,hdc\_std也需要使用最新版本。由于hdc\_std会持续更新,请从开源仓developtools\_hdc\_standard中获取,具体位置在该开源仓的prebuilt目录。 317 318 319 320### hdc\_std运行不了<a name="section15657547131615"></a> 321 322- **现象描述** 323 324 点击hdc\_std.exe文件无法运行。 325 326- **可能原因和解决方法** 327 328 hdc\_std.exe不需要安装,直接放到磁盘上就能使用,也可以添加到环境变量中。通过打开cmd执行hdc\_std命令直接使用。 329 330 331