Flutter框架跨平台鸿蒙开发——每日饮水APP的开发流程

🚀运行效果展示

Flutter框架跨平台鸿蒙开发------每日饮水APP的开发流程

前言

在快节奏的现代生活中,很多人常常忘记定时喝水,长期缺水会对身体健康造成不良影响。为了解决这个问题,我们开发了一款基于Flutter框架的跨平台每日饮水提醒APP,支持Android、iOS、Web和鸿蒙系统。本文将详细介绍该APP的开发流程、核心功能实现和技术要点。

应用介绍

🔍 功能概述

每日饮水APP是一款帮助用户养成良好饮水习惯的应用,主要功能包括:

  • ✅ 实时显示今日喝水进度
  • ✅ 支持快速添加喝水记录(100ml、200ml、300ml、500ml)
  • ✅ 自定义提醒间隔(30-120分钟)
  • ✅ 可设置每日喝水目标(1000-3000ml)
  • ✅ 支持设置提醒时间范围
  • ✅ 记录每次喝水的时间和量
  • ✅ 定时推送喝水提醒通知

🎨 界面设计

应用采用简洁现代的设计风格,主要包含以下界面:

  1. 主界面:显示今日喝水进度、快速添加按钮和今日记录列表
  2. 设置界面:提供提醒设置功能,包括启用开关、提醒间隔、每日目标和提醒时间范围

技术栈选择

技术/框架 版本 用途
Flutter 3.6.2 跨平台UI框架
Dart 3.0.0 开发语言
flutter_local_notifications 19.5.0 本地通知
shared_preferences 2.5.3 数据存储
timezone 0.10.1 时区处理
json_annotation 4.9.0 JSON序列化

开发流程和架构设计

📊 开发流程图

项目初始化
需求分析
技术选型
架构设计
UI设计
核心功能实现
测试
部署
维护和迭代

🏗️ 架构设计

应用采用分层架构设计,主要包含以下层次:

  1. 模型层 :定义数据模型,如WaterReminderSettings和WaterLog
  2. 服务层 :处理业务逻辑,如StorageService和WaterReminderService
  3. UI层 :负责界面展示,如WaterReminderScreen和WaterReminderSettingsScreen

本地通知
数据存储
时区处理
UI层
服务层
模型层
外部依赖
flutter_local_notifications
shared_preferences
timezone

核心功能实现及代码展示

1. 数据模型设计

dart 复制代码
// water_reminder_model.dart
import 'package:json_annotation/json_annotation.dart';

part 'water_reminder_model.g.dart';

/// 喝水提醒设置模型
@JsonSerializable()
class WaterReminderSettings {
  /// 是否启用提醒
  final bool isEnabled;
  
  /// 提醒间隔(分钟)
  final int reminderInterval;
  
  /// 每日喝水目标(毫升)
  final int dailyGoal;
  
  /// 开始提醒时间
  final int startHour;
  
  /// 结束提醒时间
  final int endHour;
  
  /// 构造函数
  WaterReminderSettings({
    this.isEnabled = true,
    this.reminderInterval = 60,
    this.dailyGoal = 2000,
    this.startHour = 8,
    this.endHour = 22,
  });
  
  /// 从JSON创建模型
  factory WaterReminderSettings.fromJson(Map<String, dynamic> json) =>
      _$WaterReminderSettingsFromJson(json);
  
  /// 转换为JSON
  Map<String, dynamic> toJson() => _$WaterReminderSettingsToJson(this);
}

/// 喝水记录模型
@JsonSerializable()
class WaterLog {
  /// 记录ID
  final String id;
  
  /// 喝水量(毫升)
  final int amount;
  
  /// 记录时间
  final DateTime time;
  
  /// 构造函数
  WaterLog({
    required this.id,
    required this.amount,
    required this.time,
  });
  
  /// 从JSON创建模型
  factory WaterLog.fromJson(Map<String, dynamic> json) =>
      _$WaterLogFromJson(json);
  
  /// 转换为JSON
  Map<String, dynamic> toJson() => _$WaterLogToJson(this);
}

2. 存储服务实现

dart 复制代码
// storage_service.dart
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../models/water_reminder_model.dart';

/// 本地存储服务
class StorageService {
  /// 单例实例
  static final StorageService _instance = StorageService._internal();
  
  /// SharedPreferences实例
  SharedPreferences? _prefs;
  
  /// 构造函数
  factory StorageService() => _instance;
  
  /// 内部构造函数
  StorageService._internal();
  
  /// 初始化存储服务
  Future<void> init() async {
    try {
      _prefs = await SharedPreferences.getInstance();
      debugPrint('SharedPreferences初始化成功');
    } catch (e) {
      debugPrint('SharedPreferences初始化失败: $e');
      _prefs = null;
    }
  }
  
  /// 保存喝水提醒设置
  Future<void> saveWaterReminderSettings(WaterReminderSettings settings) async {
    final json = jsonEncode(settings.toJson());
    await _prefs?.setString('water_reminder_settings', json);
  }
  
  /// 获取喝水提醒设置
  Future<WaterReminderSettings> getWaterReminderSettings() async {
    try {
      if (_prefs == null) {
        return WaterReminderSettings();
      }
      
      final json = _prefs!.getString('water_reminder_settings');
      if (json == null) {
        return WaterReminderSettings();
      }
      
      return WaterReminderSettings.fromJson(jsonDecode(json) as Map<String, dynamic>);
    } catch (e) {
      debugPrint('获取喝水提醒设置时出错: $e');
      return WaterReminderSettings();
    }
  }
  
  /// 保存喝水记录
  Future<void> saveWaterLog(WaterLog log) async {
    final jsonList = _prefs?.getString('water_logs') ?? '[]';
    final List<dynamic> logs = jsonDecode(jsonList);
    logs.add(log.toJson());
    await _prefs?.setString('water_logs', jsonEncode(logs));
  }
  
  /// 获取今日喝水记录
  Future<List<WaterLog>> getTodayWaterLogs() async {
    try {
      if (_prefs == null) {
        return [];
      }
      
      final jsonList = _prefs?.getString('water_logs') ?? '[]';
      final List<dynamic> logs = jsonDecode(jsonList);
      
      final today = DateTime.now();
      final todayStart = DateTime(today.year, today.month, today.day);
      final todayEnd = DateTime(today.year, today.month, today.day, 23, 59, 59);
      
      return logs
          .map((e) => WaterLog.fromJson(e as Map<String, dynamic>))
          .where((log) => log.time.isAfter(todayStart) && log.time.isBefore(todayEnd))
          .toList();
    } catch (e) {
      debugPrint('获取今日喝水记录时出错: $e');
      return [];
    }
  }
}

3. 提醒服务实现

dart 复制代码
// water_reminder_service.dart
import 'package:flutter/foundation.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:timezone/timezone.dart' as tz;
import '../models/water_reminder_model.dart';
import 'storage_service.dart';

/// 喝水提醒服务
class WaterReminderService {
  /// 单例实例
  static final WaterReminderService _instance = WaterReminderService._internal();
  
  /// 本地通知插件
  final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = 
      FlutterLocalNotificationsPlugin();
  
  /// 存储服务
  final StorageService _storageService = StorageService();
  
  /// 当前提醒设置
  WaterReminderSettings? _currentSettings;
  
  /// 构造函数
  factory WaterReminderService() => _instance;
  
  /// 内部构造函数
  WaterReminderService._internal();
  
  /// 初始化服务
  Future<void> init() async {
    try {
      // 初始化本地通知
      await _initLocalNotifications();
      
      // 加载设置
      _currentSettings = await _storageService.getWaterReminderSettings();
      
      // 根据设置启动或停止提醒
      if (_currentSettings?.isEnabled ?? false) {
        await startReminders();
      }
    } catch (e, stackTrace) {
      debugPrint('初始化喝水提醒服务失败: $e');
      debugPrint('堆栈跟踪: $stackTrace');
    }
  }
  
  /// 初始化本地通知
  Future<void> _initLocalNotifications() async {
    // Android配置
    const AndroidInitializationSettings initializationSettingsAndroid = 
        AndroidInitializationSettings('@mipmap/ic_launcher');
    
    // iOS配置
    const DarwinInitializationSettings initializationSettingsIOS = 
        DarwinInitializationSettings(
      requestAlertPermission: true,
      requestBadgePermission: true,
      requestSoundPermission: true,
    );
    
    // 初始化设置
    const InitializationSettings initializationSettings = InitializationSettings(
      android: initializationSettingsAndroid,
      iOS: initializationSettingsIOS,
    );
    
    await _flutterLocalNotificationsPlugin.initialize(initializationSettings);
  }
  
  /// 启动提醒
  Future<void> startReminders() async {
    if (_currentSettings == null || !_currentSettings!.isEnabled) {
      return;
    }
    
    // 取消之前的所有提醒
    await cancelAllReminders();
    
    // 获取当前时间
    final now = DateTime.now();
    
    // 计算下一次提醒时间
    DateTime nextReminderTime = now.add(
      Duration(minutes: _currentSettings!.reminderInterval),
    );
    
    // 确保提醒时间在设定的范围内
    nextReminderTime = _ensureTimeInRange(nextReminderTime);
    
    // 调度通知
    await _scheduleNotification(nextReminderTime);
    
    debugPrint('喝水提醒已启动,下一次提醒时间:$nextReminderTime');
  }
  
  /// 确保时间在设定的范围内
  DateTime _ensureTimeInRange(DateTime time) {
    if (_currentSettings == null) {
      return time;
    }
    
    final startHour = _currentSettings!.startHour;
    final endHour = _currentSettings!.endHour;
    
    // 如果时间在范围内,直接返回
    if (time.hour >= startHour && time.hour < endHour) {
      return time;
    }
    
    // 如果时间早于开始时间,设置为今天的开始时间
    if (time.hour < startHour) {
      return DateTime(
        time.year,
        time.month,
        time.day,
        startHour,
        0,
        0,
      );
    }
    
    // 如果时间晚于结束时间,设置为明天的开始时间
    return DateTime(
      time.year,
      time.month,
      time.day + 1,
      startHour,
      0,
      0,
    );
  }
  
  /// 调度通知
  Future<void> _scheduleNotification(DateTime scheduledTime) async {
    // 转换为时区时间
    final tz.TZDateTime tzScheduledTime = tz.TZDateTime.from(
      scheduledTime,
      tz.local,
    );
    
    // 创建通知详细信息
    const NotificationDetails notificationDetails = NotificationDetails(
      android: AndroidNotificationDetails(
        'water_reminder_channel',
        '喝水提醒',
        channelDescription: '定时提醒您喝水',
        importance: Importance.high,
        priority: Priority.high,
      ),
      iOS: DarwinNotificationDetails(),
    );
    
    // 调度通知
    await _flutterLocalNotificationsPlugin.zonedSchedule(
      0,
      '喝水时间到!',
      '记得喝一杯水哦,保持身体健康!',
      tzScheduledTime,
      notificationDetails,
      androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
      matchDateTimeComponents: DateTimeComponents.time,
    );
  }
  
  /// 停止提醒
  Future<void> stopReminders() async {
    await cancelAllReminders();
    debugPrint('喝水提醒已停止');
  }
  
  /// 取消所有提醒
  Future<void> cancelAllReminders() async {
    await _flutterLocalNotificationsPlugin.cancelAll();
  }
  
  /// 更新提醒设置
  Future<void> updateSettings(WaterReminderSettings newSettings) async {
    // 保存新设置
    await _storageService.saveWaterReminderSettings(newSettings);
    _currentSettings = newSettings;
    
    // 根据新设置启动或停止提醒
    if (newSettings.isEnabled) {
      await startReminders();
    } else {
      await stopReminders();
    }
  }
}

4. 主界面实现

dart 复制代码
// water_reminder_screen.dart
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../models/water_reminder_model.dart';
import '../services/storage_service.dart';
import 'water_reminder_settings_screen.dart';

/// 喝水提醒主屏幕
class WaterReminderScreen extends StatefulWidget {
  /// 构造函数
  const WaterReminderScreen({super.key});

  @override
  State<WaterReminderScreen> createState() => _WaterReminderScreenState();
}

class _WaterReminderScreenState extends State<WaterReminderScreen> {
  /// 存储服务
  final StorageService _storageService = StorageService();
  
  /// 今日喝水记录
  List<WaterLog> _todayLogs = [];
  
  /// 提醒设置
  WaterReminderSettings? _settings;
  
  /// 今日喝水总量
  int _todayTotal = 0;
  
  /// 加载数据
  Future<void> _loadData() async {
    // 加载设置
    final settings = await _storageService.getWaterReminderSettings();
    
    // 加载今日记录
    final logs = await _storageService.getTodayWaterLogs();
    
    // 计算今日总量
    final total = logs.fold(0, (sum, log) => sum + log.amount);
    
    setState(() {
      _settings = settings;
      _todayLogs = logs;
      _todayTotal = total;
    });
  }
  
  /// 添加喝水记录
  Future<void> _addWaterLog(int amount) async {
    final log = WaterLog(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      amount: amount,
      time: DateTime.now(),
    );
    
    await _storageService.saveWaterLog(log);
    await _loadData();
  }
  
  @override
  void initState() {
    super.initState();
    _loadData();
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('喝水提醒'),
        actions: [
          IconButton(
            icon: const Icon(Icons.settings),
            onPressed: () async {
              // 跳转到设置页面
              final result = await Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => const WaterReminderSettingsScreen(),
                ),
              );
              
              // 如果设置有变化,重新加载数据
              if (result == true) {
                await _loadData();
              }
            },
          ),
        ],
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            // 喝水进度卡片
            Card(
              elevation: 4,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(16),
              ),
              child: Padding(
                padding: const EdgeInsets.all(24.0),
                child: Column(
                  children: [
                    const Text(
                      '今日喝水进度',
                      style: TextStyle(
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    const SizedBox(height: 24),
                    
                    // 进度环 - 使用自定义绘制
                    SizedBox(
                      width: 200,
                      height: 200,
                      child: CustomPaint(
                        painter: _ProgressRingPainter(
                          progress: (_todayTotal / (_settings?.dailyGoal ?? 2000)).clamp(0.0, 1.0),
                        ),
                        child: Center(
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              Text(
                                '$_todayTotal',
                                style: const TextStyle(
                                  fontSize: 48,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                              Text(
                                'ml / ${_settings?.dailyGoal ?? 2000}ml',
                                style: const TextStyle(
                                  fontSize: 16,
                                  color: Colors.grey,
                                ),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                    
                    const SizedBox(height: 24),
                    
                    // 进度百分比
                    Text(
                      '${((_todayTotal / (_settings?.dailyGoal ?? 2000)) * 100).toInt()}%',
                      style: const TextStyle(
                        fontSize: 24,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ],
                ),
              ),
            ),
            
            const SizedBox(height: 24),
            
            // 快速添加按钮
            const Text(
              '快速添加',
              style: TextStyle(
                fontSize: 18,
                fontWeight: FontWeight.bold,
              ),
            ),
            
            const SizedBox(height: 16),
            
            // 使用Wrap替代GridView,避免溢出问题
            Wrap(
              spacing: 16.0,
              runSpacing: 16.0,
              alignment: WrapAlignment.spaceEvenly,
              children: [
                _buildQuickAddButton(100),
                _buildQuickAddButton(200),
                _buildQuickAddButton(300),
                _buildQuickAddButton(500),
              ],
            ),
            
            const SizedBox(height: 24),
            
            // 今日记录
            const Text(
              '今日记录',
              style: TextStyle(
                fontSize: 18,
                fontWeight: FontWeight.bold,
              ),
            ),
            
            const SizedBox(height: 16),
            
            _todayLogs.isEmpty
                ? const Center(
                    child: Padding(
                      padding: EdgeInsets.all(24.0),
                      child: Text('今日还没有喝水记录哦'),
                    ),
                  )
                : ListView.builder(
                    shrinkWrap: true,
                    physics: const NeverScrollableScrollPhysics(),
                    itemCount: _todayLogs.length,
                    itemBuilder: (context, index) {
                      final log = _todayLogs[index];
                      return Card(
                        elevation: 2,
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(12),
                        ),
                        child: Padding(
                          padding: const EdgeInsets.all(16.0),
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text(
                                    '${log.amount} ml',
                                    style: const TextStyle(
                                      fontSize: 18,
                                      fontWeight: FontWeight.bold,
                                    ),
                                  ),
                                  Text(
                                    DateFormat('HH:mm').format(log.time),
                                    style: const TextStyle(
                                      color: Colors.grey,
                                    ),
                                  ),
                                ],
                              ),
                              const Icon(
                                Icons.local_drink,
                                color: Colors.blue,
                                size: 32,
                              ),
                            ],
                          ),
                        ),
                      );
                    },
                  ),
          ],
        ),
      ),
    );
  }
  
  /// 构建快速添加按钮
  Widget _buildQuickAddButton(int amount) {
    return GestureDetector(
      onTap: () => _addWaterLog(amount),
      child: Card(
        elevation: 2,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(12),
        ),
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Icon(
                Icons.add,
                color: Colors.blue,
                size: 32,
              ),
              const SizedBox(height: 8),
              Text(
                '$amount ml',
                style: const TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

/// 自定义进度环绘制器
class _ProgressRingPainter extends CustomPainter {
  /// 进度值(0-1)
  final double progress;
  
  /// 背景色
  final Color backgroundColor;
  
  /// 进度色
  final Color progressColor;
  
  /// 线宽
  final double strokeWidth;
  
  /// 构造函数
  _ProgressRingPainter({
    required this.progress,
    this.backgroundColor = const Color(0xFFE0E0E0),
    this.progressColor = Colors.blue,
    this.strokeWidth = 15.0,
  });
  
  @override
  void paint(Canvas canvas, Size size) {
    // 计算中心点
    final center = Offset(size.width / 2, size.height / 2);
    
    // 计算半径
    final radius = (size.width - strokeWidth) / 2;
    
    // 创建背景画笔
    final backgroundPaint = Paint()
      ..color = backgroundColor
      ..strokeWidth = strokeWidth
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round;
    
    // 创建进度画笔
    final progressPaint = Paint()
      ..color = progressColor
      ..strokeWidth = strokeWidth
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round;
    
    // 绘制背景圆环
    canvas.drawCircle(center, radius, backgroundPaint);
    
    // 绘制进度圆环
    final arcAngle = progress * 2 * 3.14159265359;
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius),
      -0.5 * 3.14159265359, // 起始角度(-90度)
      arcAngle, // 扫描角度
      false, // 是否使用中心点
      progressPaint,
    );
  }
  
  @override
  bool shouldRepaint(covariant _ProgressRingPainter oldDelegate) {
    return oldDelegate.progress != progress ||
           oldDelegate.backgroundColor != backgroundColor ||
           oldDelegate.progressColor != progressColor ||
           oldDelegate.strokeWidth != strokeWidth;
  }
}

5. 鸿蒙系统适配

为了支持鸿蒙系统,我们需要进行以下适配工作:

  1. 添加鸿蒙平台支持 :在pubspec.yaml中添加鸿蒙平台配置
  2. 处理平台特定API:使用条件编译处理不同平台的API差异
  3. 测试鸿蒙设备:在鸿蒙设备或模拟器上进行测试
yaml 复制代码
# pubspec.yaml
flutter:
  uses-material-design: true
  assets:
    - assets/images/
  # 添加鸿蒙平台支持
  plugin:
    platforms:
      ohos:
        package: com.example.flutter_text
        pluginClass: FlutterTextPlugin

测试和部署

🧪 测试流程

  1. 单元测试:对核心功能进行单元测试
  2. 集成测试:测试不同组件之间的交互
  3. UI测试:测试界面布局和交互
  4. 跨平台测试:在不同平台上进行测试

🚀 部署流程

  1. Web部署:

    bash 复制代码
    flutter build web
  2. Android部署:

    bash 复制代码
    flutter build apk
  3. iOS部署:

    bash 复制代码
    flutter build ios
  4. 鸿蒙部署:

    bash 复制代码
    flutter build ohos

遇到的问题和解决方案

1. 进度环显示异常

问题 :在某些设备上,使用两个CircularProgressIndicator嵌套的方式显示进度环时,会出现异常显示。

解决方案 :使用自定义绘制的_ProgressRingPainter类来绘制进度环,确保进度环能够正确显示。

2. 快速添加按钮溢出

问题 :在小屏幕设备上,使用GridView.count时,快速添加按钮会溢出屏幕。

解决方案 :将GridView.count替换为Wrap组件,使按钮能够根据屏幕宽度自动换行。

3. 鸿蒙系统数据库初始化失败

问题 :在鸿蒙系统上,调用getApplicationDocumentsDirectory方法时会失败。

解决方案 :由于喝水提醒功能只使用SharedPreferences,不依赖数据库,因此跳过了数据库初始化步骤。

4. 时区初始化错误

问题 :在某些平台上,调用tz.initializeTimeZones()方法时会出现方法未找到的错误。

解决方案 :移除了tz.initializeTimeZones()方法调用,该方法在最新版本的timezone库中已不再需要。

总结和展望

📋 项目总结

通过本项目,我们成功开发了一款基于Flutter框架的跨平台每日饮水提醒APP,支持Android、iOS、Web和鸿蒙系统。应用具有以下特点:

  1. 跨平台兼容:使用Flutter框架实现一次开发,多平台运行
  2. 功能完整:包含喝水记录、提醒设置、进度展示等核心功能
  3. UI美观:采用现代化的设计风格,界面简洁易用
  4. 性能优良:优化了应用启动和运行性能
  5. 稳定性高:添加了异常处理机制,提高了应用的稳定性

🔮 未来展望

  1. 添加数据分析功能:分析用户的喝水习惯,提供个性化建议
  2. 支持多用户:添加用户登录功能,支持多设备同步
  3. 添加社交功能:支持用户之间的互动和分享
  4. 优化通知机制:提供更灵活的通知设置
  5. 支持更多语言:添加多语言支持

结论

Flutter框架为跨平台开发提供了强大的支持,使我们能够高效地开发出兼容多种平台的应用。通过本项目的实践,我们深入了解了Flutter框架的特性和鸿蒙系统的适配要点,积累了宝贵的跨平台开发经验。

每日饮水APP的开发不仅解决了用户忘记喝水的问题,也展示了Flutter框架在跨平台开发中的优势。我们相信,随着Flutter框架和鸿蒙系统的不断发展,跨平台开发将变得更加高效和便捷。


欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

相关推荐
youyin5 天前
HarmonyOS ArkUI 组件与自定义组件零基础:从搭页面到组件化开发
华为·harmonyos
HwJack205 天前
【HarmonyOS开发小实践】ArkTS 从 TypeScript 到方舟语言的演进
华为·harmonyos
张星河zen5 天前
4096卡、8EFLOPS、7.2T NPO:华为昇腾960超节点详解
华为·ai训练·ai推理·超节点·npo·昇腾960·hi-one
君赏6 天前
棉宇宙 Flutter 热更新是如何落地的
flutter
云运维笔记6 天前
华为设备IP地址配置全攻略
运维·网络·计算机网络·华为
威哥爱编程6 天前
HarmonyOS 7 星盾机密风控实战:设备风险因子端侧融合计算,可用不可见
harmonyos·arkts
恋猫de小郭6 天前
AndroidX 新增 Security State ,支持可编程的系统安全状态查询
android·前端·flutter
威哥爱编程6 天前
HarmonyOS 7 应用快启实战:关键资源预加载进内存,冷启告别白屏
华为·harmonyos·arkts
zihan5186 天前
自己做软件日记9/21 得到了一个良好的文件结构框架
后端·flutter·前端框架·android studio