基于HarmonyOS Next的美食发现应用开发实战

基于HarmonyOS Next的美食发现应用开发实战

在移动应用开发领域,美食类应用始终占据重要地位。HarmonyOS Next凭借其分布式能力与流畅性能,为美食应用开发提供了全新可能。本文将结合AppGallery Connect(AGC)服务,手把手教你打造一个功能完整的美食发现应用。

一、开发环境准备

首先确保环境配置正确:

  1. 安装DevEco Studio 4.1+(支持HarmonyOS Next)
  2. 在AGC控制台创建项目并启用以下服务: 认证服务(手机/邮箱登录)云数据库(存储美食数据)云存储(美食图片管理)
  3. 在项目中集成AGC SDK:
// oh-package.json5
"dependencies": {
  "@hw-agconnect/auth-ohos": "^1.9.1",
  "@hw-agconnect/clouddb-ohos": "^1.9.1",
  "@hw-agconnect/storage-ohos": "^1.9.1"
}

二、用户认证模块实现

使用AGC认证服务实现安全登录:

// src/main/ets/pages/LoginPage.ets
import { AGConnectAuth, AGCAuth } from '@hw-agconnect/auth-ohos';

@Entry
@Component
struct LoginPage {
  @State phone: string = ''
  @State verifyCode: string = ''

  // 发送短信验证码
  sendSMSCode() {
    AGConnectAuth.getInstance().requestVerifyCode(this.phone, AGCAuth.VerifyCodeAction.LOGIN)
      .then(() => { prompt.showToast({ message: '验证码已发送' }) })
      .catch(err => { console.error('发送失败: ' + JSON.stringify(err)) })
  }

  // 手机号验证码登录
  phoneLogin() {
    const credential = AGCAuth.PhoneAuthProvider.credentialWithVerifyCode(this.phone, this.verifyCode)
    AGConnectAuth.getInstance().signIn(credential)
      .then(user => {
        prompt.showToast({ message: `欢迎 ${user.displayName}` })
        router.replaceUrl({ url: 'pages/HomePage' })
      })
      .catch(err => { console.error('登录失败: ' + JSON.stringify(err)) })
  }

  build() {
    Column() {
      TextInput({ placeholder: '输入手机号' })
        .onChange(val => this.phone = val)
      
      Row() {
        TextInput({ placeholder: '验证码' })
          .onChange(val => this.verifyCode = val)
          .layoutWeight(1)
        
        Button('获取验证码')
          .onClick(() => this.sendSMSCode())
      }

      Button('登录', { type: ButtonType.Capsule })
        .onClick(() => this.phoneLogin())
        .margin(20)
    }
  }
}

三、云端数据结构设计

在AGC云数据库控制台创建美食数据模型:

// 定义美食对象类型
@Class
export class FoodInfo {
  @Field()
  id: number = 0;  // 唯一标识

  @Field({ isIndex: true })
  name: string = '';  // 美食名称

  @Field()
  category: string = '';  // 分类(川菜/粤菜等)

  @Field()
  rating: number = 0;  // 评分(0-5)

  @Field()
  coverUrl: string = '';  // 封面图URL

  @Field()
  location: string = '';  // 店铺位置

  // 构造器
  constructor(name?: string, rating?: number) {
    this.name = name || '';
    this.rating = rating || 0;
  }
}

四、美食数据云端交互

实现云端数据的增删改查操作:

// src/main/ets/utils/CloudDBManager.ets
import { clouddb } from '@hw-agconnect/clouddb-ohos';

export class FoodManager {
  private cloudDBZone: clouddb.CloudDBZone | null = null;

  // 初始化云数据库
  async initCloudDB() {
    const agcCloudDB = clouddb.CloudDBZoneWrapper.getInstance();
    const zoneConfig = new clouddb.CloudDBZoneConfig('FoodZone', clouddb.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE);
    this.cloudDBZone = await agcCloudDB.openCloudDBZone(zoneConfig);
  }

  // 添加美食数据
  async addFood(food: FoodInfo): Promise<boolean> {
    try {
      const result = await this.cloudDBZone?.executeUpsert(food);
      return result?.length > 0;
    } catch (err) {
      console.error('添加失败: ' + JSON.stringify(err));
      return false;
    }
  }

  // 查询所有美食(带分页)
  async queryAllFoods(page: number, pageSize: number): Promise<FoodInfo[]> {
    const query = clouddb.CloudDBZoneQuery.where(FoodInfo).limit(pageSize, page * pageSize);
    try {
      const snapshot = await this.cloudDBZone?.executeQuery(query, clouddb.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY);
      return snapshot?.getSnapshotObjects() || [];
    } catch (err) {
      console.error('查询失败: ' + JSON.stringify(err));
      return [];
    }
  }
}

五、图片上传与展示

利用云存储管理美食图片:

// src/main/ets/utils/ImageManager.ets
import { agconnect } from '@hw-agconnect/core-ohos';
import { storage } from '@hw-agconnect/storage-ohos';

export class ImageUploader {
  // 上传图片到云存储
  static async uploadImage(fileUri: string): Promise<string> {
    try {
      const storageManagement = agconnect.storage().storageManagement();
      const reference = storageManagement.storageReference(`foods/${new Date().getTime()}.jpg`);
      
      await reference.putFile(fileUri);
      return await reference.getDownloadURL();
    } catch (err) {
      console.error('上传失败: ' + JSON.stringify(err));
      return '';
    }
  }

  // 获取图片显示组件
  @Builder
  static FoodImage(url: string) {
    if (url) {
      Image(url)
        .width('100%')
        .height(200)
        .objectFit(ImageFit.Cover)
    } else {
      Image($r('app.media.placeholder'))
        .width('100%')
        .height(200)
    }
  }
}

六、美食发现页面实现

整合各模块实现核心功能:

// src/main/ets/pages/HomePage.ets
import { FoodManager } from '../utils/CloudDBManager';
import { ImageUploader } from '../utils/ImageManager';

@Entry
@Component
struct HomePage {
  private foodManager = new FoodManager();
  @State foodList: FoodInfo[] = []
  @State currentPage: number = 0
  @State newFood: FoodInfo = new FoodInfo()

  // 页面加载时初始化
  aboutToAppear() {
    this.foodManager.initCloudDB().then(() => this.loadFoods());
  }

  // 加载美食数据
  loadFoods() {
    this.foodManager.queryAllFoods(this.currentPage, 10).then(list => {
      this.foodList = [...this.foodList, ...list];
    });
  }

  // 添加新美食
  async addNewFood() {
    if (await this.foodManager.addFood(this.newFood)) {
      prompt.showToast({ message: '添加成功!' });
      this.newFood = new FoodInfo();
      this.loadFoods();
    }
  }

  build() {
    Column() {
      // 美食列表
      List({ space: 10 }) {
        ForEach(this.foodList, (item: FoodInfo) => {
          ListItem() {
            Column() {
              ImageUploader.FoodImage(item.coverUrl)
              Text(item.name).fontSize(18).margin({ top: 5 })
              Row() {
                ForEach([1, 2, 3, 4, 5], (star) => {
                  Image($r(star <= item.rating ? 'app.media.star_filled' : 'app.media.star_empty'))
                    .width(20)
                    .height(20)
                    .margin({ right: 2 })
                })
              }
              Text(`位置: ${item.location}`).fontColor(Color.Gray)
            }
          }
        })
      }

      // 加载更多
      Button('加载更多', { type: ButtonType.Normal })
        .onClick(() => {
          this.currentPage++;
          this.loadFoods();
        })
        .margin(15)
    }
  }
}

七、数据同步与设备协同

实现跨设备数据同步:

// 监听云端数据变化
setupCloudListener() {
  const subscribe = clouddb.CloudDBZoneSnapshot.forSubscribe();
  const query = clouddb.CloudDBZoneQuery.where(FoodInfo);
  
  this.cloudDBZone?.subscribeSnapshot(query, 
    clouddb.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY,
    (error, snapshot) => {
      if (snapshot) {
        this.foodList = snapshot.getSnapshotObjects();
      }
    }
  );
}

// 跨设备分享美食
shareToDevice(food: FoodInfo) {
  try {
    const deviceManager = deviceManager.getDeviceManager();
    const devices = deviceManager.getTrustedDeviceListSync();
    
    if (devices.length > 0) {
      const params = {
        'foodId': food.id.toString(),
        'message': `发现美食:${food.name}`
      };
      
      deviceManager.startAbilityByCall({
        deviceId: devices[0].deviceId,
        bundleName: 'com.example.foodapp',
        abilityName: 'DetailAbility',
        parameters: params
      });
    }
  } catch (err) {
    console.error('设备协同失败: ' + JSON.stringify(err));
  }
}

八、性能优化技巧

提升应用流畅度:

  1. 图片懒加载优化
// 使用LazyForEach替代ForEach
LazyForEach(this.foodList, 
  (item: FoodInfo) => {
    ListItem() {
      FoodItemView({ food: item })
    }
  },
  item => item.id.toString()
)

  1. 数据缓存策略
// 混合查询策略(优先本地缓存)
const policy = clouddb.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_LOCAL_ONLY;
const snapshot = await this.cloudDBZone?.executeQuery(query, policy);

  1. 渲染优化
@Component
struct FoodItemView {
  @Prop food: FoodInfo

  build() {
    Column() {
      // 使用@Reusable复用组件
      Image(this.food.coverUrl)
        .syncLoad(true) // 启用同步加载避免闪烁
      // 使用cachedImage避免重复解码
      Text(this.food.name).fontSize(18)
    }
    .cachedImage(true) // 启用图片缓存
    .reuseId(`food_${this.food.id}`) // 设置复用ID
  }
}

九、项目扩展方向

  1. 智能推荐功能:集成AGC预测服务,基于用户浏览历史推荐美食
  2. AR导航功能:使用HarmonyOS ARKit实现店铺AR导航
  3. 实时点评系统:通过AGC实时数据库实现用户点评即时同步
  4. 健康管理:对接华为Health Kit获取用户健康数据,提供饮食建议

通过本教程,您已掌握了使用HarmonyOS Next和AppGallery Connect开发美食应用的核心技术。从用户认证到数据存储,从图片管理到设备协同,这些技术栈同样适用于社交、电商等多种应用场景。HarmonyOS的分布式架构让多设备协同变得简单高效,而AGC的BaaS服务则大幅降低了后端开发复杂度。

随着HarmonyOS生态持续完善,开发者将获得更多创新可能。建议持续关注:

  • 原子化服务开发
  • 元服务卡片技术
  • 跨设备流转能力优化
  • 全新声明式UI范式

掌握这些前沿技术,将使您的应用在万物互联时代脱颖而出。

全部评论

相关推荐

07-10 11:08
门头沟学院 Java
投递京东等公司9个岗位
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-10 11:55
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务