智能客服
你问我答,随时在线为你解决问题
本文档介绍汽车类HarmonyOS应用的架构设计实践,提供常见的资讯、购车、商城以及充电服务等功能,帮助开发者快速构建一款汽车类应用。
实践应用框架代码运行图,开发者可以基于框架代码替换相关资源文件,以保证应用良好的使用体验。
|
|
根据行业应用的功能,按照高内聚,低耦合的原则,常见汽车类应用功能以及职责划分模块如下,开发者在实际设计过程中,可以根据模块的复杂程度实际情况再进一步细分:
模块名称 | 功能点 |
|---|---|
探索 | 行业资讯 |
购车 | 产品详情,购车指南 |
商城 | 商品搜索,商品详情,商品购买 |
服务 | 充电服务,服务门店 |
我的 | 我的车辆,我的订单,我的积分,我的家充 |
通用 | 资源,国际化,导航 |
应用分层模块类型划分指导,参见分层模块化实践。
产品定制层:本实践只涉及手机端,设计为一个HAP,包含页面框架、导航、手机独有资源等。
基础特性层:“探索”、“购车” 等功能模块设计为HAR包,被上层引用。
公共能力层:本实践将“应用路由”、“基础工具”、“DFX”等基础公共模块打包为Har包被上层业务组件引用,其中路由管理划分到公共组件。

根据本应用功能的模块以及依赖,分解对基础服务以及三方的依赖,逻辑视图如下:

介绍行业应用通用的公共关键技术,详见公共关键技术方案。
功能设计

设计
使用Scan Kit(统一扫码服务)实现扫码能力,本示例代码使用默认界面扫码能力。
能力 | 限制条件 |
|---|---|
scanBarcode (默认界面扫码) | 系统体验一致的扫码体验,系统预授权,暂不支持悬浮屏、分屏场景,相册扫码只支持单码识别。 |
customScan (自定义界面扫码) | 适用对扫码有定制需求的开发,需要授权使用相机权限;需要开发者自行实现扫码的人机交互界面。 |
代码参考
代码详情参见扫码充电代码实现。
功能设计
提供最优站点列表以及路径规划。常见页面路径:首页→服务→最优站点,功能页面如下图所示:

方案设计
代码参考
申请ohos.permission.LOCATION和ohos.permission.APPROXIMATELY_LOCATION权限,您需要在module.json5配置文件中声明所需要的权限,具体可参考声明权限。
代码详情参见最优站点代码实现。
结合HarmonyOS,针对行业的创新场景设计,开发者可以参考行业创新设计方案,实现创新场景代码。
场景说明
最优站点页面,点击站点导航图标拉起导航类应用,导航应用单独一个界面。通用方案:使用隐式want能力,启动设备内地图应用,多个应用时会弹出对话框显示多个应用图标,用户选择。如果本机没有安装地图导航应用,会有类似“请安装地图应用”提示,用户需要先下载导航应用,操作繁琐,体验差。
创新设计
利用元服务免安装能力,导航元服务(相应元服务已上架)内嵌展示在应用内。在用户没有安装导航应用情况下,也能正常打开地图导航功能,实现导航能力。

本篇代码非应用的全量代码,只包括应用的部分框架代码。
框架代码中的登录验证仅提供UI界面,手机号输入满11位后,任意密码均可登录,开发者需自行实现鉴权认证。
软件要求
硬件要求
环境搭建
历史工程迁移
开发者使用HarmonyOS 6.0.0 Release及以上版本导入代码,使用一体化的历史工程迁移能力,帮助开发者快速完成工程转换。
本篇代码非应用的全量代码,只包括脱敏后的应用框架代码,开发者可以通过链接下载全量的框架代码。
整个框架代码结构分为5个HAR包,所有的HAR在同一个IDE工程中维护开发。

5个HAR分别为buyingCar,explore,mine,service,shoppingMall。
- ├── common/src/main/ets // 公共模块
- │ ├── components
- │ │ ├── NavItem.ets // nav组件
- │ │ ├── PageHeaderComp.ets // 二级页面头部组件
- │ │ └── ShopItem.ets // shop组件
- │ ├── constants
- │ │ ├── CommonConstants.ets // 公共样式
- │ │ ├── NavConstants.ets // nav样式
- │ │ └── TabConstants.ets // tab样式
- │ ├── model
- │ │ ├── BuyingCarModel.ets // 购车数据模型
- │ │ ├── CommodityModel.ets // 商城数据模型
- │ │ ├── ExploreModel.ets // 探索数据模型
- │ │ ├── LazyDataSource.ets // 懒加载数据
- │ │ ├── NavModel.ets // nav数据模型
- │ │ └── ShopModel.ets // shop数据模型
- │ └── utils
- │ ├── LoggerUtil.ets
- │ ├── PermissionsUtil.ets // 权限管理工具类
- │ └── PreferencesUtil.ets // 数据存储工具类
- ├── entry/src/main/ets // 主页面
- │ ├── constants
- │ │ └── TabConstants.ets // tab样式
- │ ├── entryability
- │ │ └── EntryAbility.ets // 程序入口
- │ └── pages
- │ ├── LoginPage.ets // 登录页
- │ ├── NavigationPage.ets // Navigation根页面
- │ ├── PrivacyPolicyPage.ets // 隐私政策页面
- │ ├── SplashScreenPage.ets // 闪屏页
- │ ├── SplashScreenPage2.ets // 闪屏页2
- │ └── TabPage.ets // tab页
- ├── features
- │ ├── buyingcar/src/main/ets // 购车
- │ │ ├── components
- │ │ │ ├── LearnMoreItemComp.ets // 了解更多item组件
- │ │ │ ├── MarqueeImageComp.ets // 走马灯图片
- │ │ │ ├── SwiperItemComp.ets // 购车swiperItem组件
- │ │ │ └── VehicleModelActivities.ets // 车型item组件
- │ │ └── pages
- │ │ ├── BuyingCarDetailPage.ets
- │ │ └── BuyingCarPage.ets // 购车tab页
- │ ├── explore/src/main/ets // 探索
- │ │ ├── components
- │ │ │ ├── ActivityComp.ets // 活动swiper页
- │ │ │ ├── ActivityItemComp.ets // 活动item组件
- │ │ │ ├── RealTimeInfoComp.ets // 咨询swiper页
- │ │ │ └── RecommendationComp.ets // 推荐swiper页
- │ │ ├── constants
- │ │ │ └── RecommendationConstants.ets // 探索tab页
- │ │ └── pages
- │ │ └── ExplorePage.ets
- │ ├── mine/src/main/ets // 我的
- │ │ ├── components
- │ │ │ └── MajorList.ets // 单个组件
- │ │ ├── constants
- │ │ │ ├── HeaderConstants.ets // 头部样式
- │ │ │ └── MajorConstants.ets // major样式
- │ │ ├── model
- │ │ │ └── MajorModel.ets // major模型
- │ │ └── pages
- │ │ ├── MinePage.ets // 我的tab页
- │ │ └── SettingsPage.ets // 设置页面
- │ ├── service/src/main/ets // 服务
- │ │ ├── components
- │ │ │ └── SheetTransition.ets // sheet模态框
- │ │ ├── constants
- │ │ │ └── ServiceConstants.ets // 服务样式
- │ │ ├── model
- │ │ │ └── StationModel.ets // station模型
- │ │ ├── pages
- │ │ │ ├── MyCharge.ets // 我的充电页
- │ │ │ ├── OptimalStation.ets // 最优站点页
- │ │ │ └── ServicePage.ets // 服务tab页
- │ └── shoppingMall/src/main/ets // 商城
- │ ├── components
- │ │ └── CommodityItemComp.ets // 商城列表item组件
- │ ├── constants
- │ │ └── ShoppingMallConstants.ets // 商城样式
- │ └── pages
- │ ├── CommodityDetailPage.ets // 商城详情
- │ └── ShoppingMallPage.ets // 商城tab页
- └── entry/src/main/resources // 资源文件目录
- // features\service\src\main\ets\pages\ServicePage.ets
- Row() {
- ForEach(this.mapShopList, (item: shopInfo, index: number) => {
- Row() {
- ShopItem({ itemData: item })
- }.onClick(() => {
- if (item.title === '扫码充电') {
- // 定义扫码参数options
- let options: scanBarcode.ScanOptions = {
- scanTypes: [scanCore.ScanType.ALL], // 设置扫码类型,默认扫码ALL(全部码类型)
- enableMultiMode: true, // 是否开启多码识别,默认false。
- enableAlbum: true // 是否开启相册,默认true, 此参数只控制默认界面扫码能力中的相册扫码且只支持单码识别。
- };
- try {
- scanBarcode.startScanForResult(getContext(this), options).then((result: scanBarcode.ScanResult) => {
- // 收到扫码结果后返回
- Logger.info('Promise scan result: %{public}s', JSON.stringify(result));
- // 处理扫码结果
- this.showScanResult(result);
- }).catch((error: BusinessError) => {
- Logger.error('Promise error: %{public}s', JSON.stringify(error));
- });
- } catch (error) {
- Logger.error('failReason: %{public}s', JSON.stringify(error));
- }
- }
- if (item.title === '最优站点') {
- this.pageInfos.pushPath({ name: 'OptimalStation' });
- } else if (item.title === '我的充电') {
- this.pageInfos.pushPath({ name: 'MyCharge' });
- }
- })
-
- if (index !== this.mapShopList.length - 1) {
- Line().LineStyle();
- }
- })
- }
- .width(CommonConstants.COLUMN_WIDTH)
- .justifyContent(FlexAlign.SpaceEvenly)
开发者也可调用customScan (自定义界面扫码)接口能力,自定义实现扫码界面,需要申请相机权限,需要在配置文件module.json5里添加:ohos.permission.CAMERA,参见应用权限列表。适用于对扫码界面有个性化定制的场景。
使用HarmonyOS Map Kit(地图服务)能力。
- "requestPermissions": [
- {
- "name": "ohos.permission.LOCATION",
- "reason": "$string:EntryAbility_desc",
- "usedScene": {
- "abilities": [
- "EntryAbility"
- ],
- "when": "always"
- }
- },
- {
- "name": "ohos.permission.APPROXIMATELY_LOCATION",
- "reason": "$string:EntryAbility_desc",
- "usedScene": {
- "abilities": [
- "EntryAbility"
- ],
- "when": "always"
- }
- }
- ]
使用MapComponent地图组件在页面中放置地图。MapComponentController是地图组件的主要功能入口类,用来操作地图,与地图有关的所有方法从此处接入。它所承载的工作包括:地图类型切换(如标准地图、空地图)、改变地图状态(中心点坐标和缩放级别)、添加点标记(Marker)、绘制几何图形(MapPolyline、MapPolygon、MapCircle)、各类事件监听等。
- // features\service\src\main\ets\pages\OptimalStation.ets
- @Entry
- @Component
- export struct OptimalStation {
- @StorageProp('avoidArea') topHeight: number = 0;
- private mapOption?: mapCommon.MapOptions;
- @State addressName: string = '';
- private callback?: AsyncCallback<map.MapComponentController>;
- private mapController?: map.MapComponentController;
- // 地图初始化经纬度,可自定义。
- private latLng: mapCommon.LatLng = {
- latitude: 31.97413747571286,
- longitude: 118.77314161376894
- }
- @State addressString: string = '';
- @Consume('pageInfos') pageInfos: NavPathStack;
-
- build() {
- NavDestination(){
- Stack({ alignContent: Alignment.Bottom }) {
- MapComponent({ mapOptions: this.mapOption, mapCallback: this.callback }).width('100%').height('100%');
- // ...
- Row() {
- // 半模态框
- SheetTransition({
- StationList: Station.getStationList(),
- addressName: this.addressName
- })
- }.margin({ bottom: 220 })
- }
- }
- .hideTitleBar(true)
- .onReady(()=>{
- // 地图初始化参数,设置地图中心点坐标及层级
- this.mapOption = {
- position: {
- target: this.latLng,
- zoom: 14
- },
- zoomControlsEnabled: false,
- myLocationControlsEnabled: true
- };
-
- // 地图初始化的回调
- this.callback = async (err, mapController) => {
- if (!err) {
- // 获取地图的控制器类,用来操作地图
- this.mapController = mapController;
- // 启用我的位置图层
- this.mapController?.setMyLocationEnabled(true);
- this.mapController.on("mapLoad", () => {
- });
- // 监听“我的位置”按钮点击事件
- this.mapController.on("myLocationButtonClick", () => {
- this.getMyLocation();
- });
- // 初始化我的位置
- this.getMyLocation();
- }
- };
- })
- }
- }
由于框架示例代码访问API受限,目前最优站点列表数据来源是本地数据,数据文件位置:features>service src/main/ets/model/StationModel.ets。
开发者可以基于此示例代码,使用位置搜索能力,查找相关POI,根据响应替换本地数据,在此基础上,根据响应使用地图绘制能力,在地图上设置图标,效果更佳。