鸿蒙原生API与OnsenUI组件的双向通信实现

📖 引言

项目已经开源:https://gitcode.com/nutpi/harmony_cordova_onsenui

在鸿蒙Cordova应用开发中,OnsenUI作为Web端UI框架需要与原生ArkTS层进行深度集成,实现Web组件对系统API的调用。本项目基于实际的鸿蒙PC端Cordova应用,展示了OnsenUI组件与原生层的完整双向通信实现。

本文将基于项目中的真实代码,详细解析OnsenUI组件如何通过Cordova桥接层调用鸿蒙原生API,包括性能优化、界面渲染、事件处理等核心功能的实现。通过分析项目中16个OnsenUI组件的集成实践,读者将掌握鸿蒙Cordova双向通信的实际开发技巧和最佳实践。

🔗 通信架构设计

通信层次结构

架构设计理念: 鸿蒙Cordova双向通信采用分层解耦的设计模式,通过标准化的接口实现Web技术与原生能力的无缝集成。整个通信链路分为四个核心层次,每一层都有明确的职责边界和数据流转协议。

通信流程说明: 实线箭头表示从Web层到原生层的调用流程,虚线箭头表示从原生层到Web层的数据回传和事件通知。这种双向通信机制确保了数据的实时同步和状态的一致性管理。

核心通信机制

javascript 复制代码
// 项目中的实际性能监控和通信实现
// 基于 index.html 中的性能监控系统

// 性能监控函数 - 实际项目代码
function initPerformanceMonitor() {
    let frameCount = 0;
    let lastTime = performance.now();
    
    // 监控帧率
    function measureFPS() {
        frameCount++;
        const currentTime = performance.now();
        
        if (currentTime - lastTime >= 1000) {
            const fps = Math.round((frameCount * 1000) / (currentTime - lastTime));
            console.log('当前FPS:', fps);
            
            // 如果FPS低于55,输出警告
            if (fps < 55) {
                console.warn('性能警告: FPS低于55,当前值:', fps);
            }
            
            frameCount = 0;
            lastTime = currentTime;
        }
        
        requestAnimationFrame(measureFPS);
    }
    
    requestAnimationFrame(measureFPS);
    
    // 监控页面加载性能
    const navigationStart = performance.timing.navigationStart;
    const loadComplete = performance.timing.loadEventEnd;
    const loadTime = loadComplete - navigationStart;
    
    console.log('页面加载时间:', loadTime + 'ms');
}

// 优化后的页面跳转函数 - 在右侧内容区域加载
function pushPage(page) {
    const startTime = performance.now();
    
    var contentNavigator = document.getElementById('contentNavigator');
    
    // 监控页面切换性能
    contentNavigator.resetToPage(page).then(() => {
        const endTime = performance.now();
        const loadTime = endTime - startTime;
        
        console.log(`页面 ${page} 加载时间: ${loadTime.toFixed(2)}ms`);
        
        // 如果加载时间超过100ms,输出优化建议
        if (loadTime > 100) {
            console.warn('页面加载较慢,建议优化:', {
                page: page,
                loadTime: loadTime,
                suggestions: [
                    '减少页面中的DOM元素数量',
                    '优化CSS样式,避免复杂选择器',
                    '使用CSS3硬件加速',
                    '延迟加载非关键资源'
                ]
            });
        }
    });
}

通信管理器核心技术实现深度解析:

HarmonyCommunicationManager类是整个双向通信系统的核心控制器,它实现了Web层与原生层之间的可靠通信机制。该类采用了现代JavaScript的异步编程模式,通过Promise封装了传统的回调式API,大大提升了代码的可读性和可维护性。

回调管理机制: 系统使用Map数据结构管理回调函数,每个原生调用都会生成一个唯一的回调ID。这种设计解决了传统Cordova开发中回调函数管理混乱的问题,确保了每个异步调用都能正确匹配其对应的回调处理函数。generateCallbackId方法通过时间戳和递增计数器的组合,保证了ID的全局唯一性。

Promise封装策略: callNative方法将传统的cordova.exec回调模式封装为Promise,这种设计使得开发者可以使用现代的async/await语法进行异步编程。Promise的resolve和reject分别对应成功和失败的回调,通过handleSuccesshandleError方法进行统一处理,确保了错误处理的一致性。

事件监听器管理: eventListenersMap用于管理从原生层到Web层的事件通知,这种设计支持了真正的双向通信。当原生层发生状态变化时,可以主动向Web层推送事件,实现了数据的实时同步。

初始化时序控制: initCordovaReady方法通过监听deviceready事件确保Cordova框架完全初始化后再建立通信连接,这种时序控制避免了因初始化顺序问题导致的通信失败。

🛠️ 原生插件开发

ArkTS插件基础结构

实战场景背景: 在智能办公应用中,我们需要获取设备的基本信息用于适配不同屏幕尺寸,监控网络状态以决定是否启用离线模式,以及实现文档的本地存储功能。这些需求都需要通过原生插件来实现。

技术实现挑战: ArkTS插件开发需要处理异步调用、错误处理、数据序列化等多个技术难点。我们的解决方案采用了装饰器模式、异常处理机制和标准化的数据返回格式。

ArkTS插件开发技术实现深度解析:

HarmonyNativePlugin类展示了鸿蒙原生插件开发的完整技术栈,从系统API调用到数据处理再到事件通知,每个环节都体现了现代移动应用开发的最佳实践。

装饰器模式应用: @CordovaMethod装饰器是插件系统的核心技术,它将普通的TypeScript方法转换为可被Web层调用的Cordova插件方法。这种声明式的编程模式大大简化了插件开发的复杂度,开发者只需关注业务逻辑的实现,而无需处理底层的通信协议。

异步编程模式: 所有插件方法都采用async/await模式,这种设计确保了原生API调用的非阻塞执行。在鸿蒙系统中,大部分系统API都是异步的,这种编程模式与系统特性完美匹配,避免了主线程阻塞导致的用户界面卡顿。

错误处理机制: 每个方法都采用了统一的错误处理模式,通过try-catch捕获异常并返回标准化的错误信息。错误代码的设计(如DEVICE_INFO_ERROR、FILE_WRITE_ERROR)为Web层的错误处理提供了精确的错误分类,便于实现针对性的错误恢复策略。

数据序列化策略: 插件返回的数据都采用了标准化的JSON格式,包含success标志、data数据、timestamp时间戳等字段。这种设计确保了数据在跨层传输过程中的完整性和一致性,同时为后续的数据处理提供了便利。

事件驱动通信: sendEventToWeb方法实现了从原生层到Web层的主动事件推送,通过runJavaScript执行JavaScript代码来触发Web层的自定义事件。这种设计实现了真正的双向通信,使得原生层可以主动向Web层推送状态变化通知。

核心系统功能实现

基于项目中的CoreHarmony模块,展示了实际的系统级功能实现:

🎨 OnsenUI组件集成

实际OnsenUI组件展示

项目组件概览: 本项目实现了16个OnsenUI组件的完整集成,包括Button、List、Dialog、Input、Card、Tabbar、Carousel、FAB、PullHook、Splitter、Popover、Progress、Segment、Modal、Icons、Navbar等。每个组件都经过性能优化和鸿蒙环境适配。

主界面布局实现: 基于项目中的实际主界面代码:

Button组件实际实现

基于项目中的button.html,展示了完整的OnsenUI按钮组件实现:

html 复制代码
<!-- 项目中的实际Button组件示例 - button.html -->
<ons-page>
    <ons-toolbar>
        <div class="left">
            <ons-back-button>返回</ons-back-button>
        </div>
        <div class="center">Button 按钮</div>
    </ons-toolbar>

    <div class="content-wrapper">
        <div class="info-box">
            <div style="display: flex; align-items: center;">
                <ons-icon icon="md-info" class="info-box-icon"></ons-icon>
                <div>
                    <div class="info-box-title">Button 组件</div>
                    <div class="info-box-content">OnsenUI 提供了多种样式的按钮,适用于不同的使用场景</div>
                </div>
            </div>
        </div>
        
        <h3 class="section-title">基础按钮</h3>
        
        <!-- 代码示例容器 -->
        <div class="code-example-container">
            <!-- 演示区域 -->
            <div class="code-demo-area">
                <p style="margin: 10px 0;">
                    <ons-button>默认按钮</ons-button>
                </p>
                <p style="margin: 10px 0;">
                    <ons-button modifier="light">Light</ons-button>
                </p>
                <p style="margin: 10px 0;">
                    <ons-button modifier="outline">Outline</ons-button>
                </p>
                <p style="margin: 10px 0;">
                    <ons-button modifier="cta">CTA</ons-button>
                </p>
                <p style="margin: 10px 0;">
                    <ons-button modifier="quiet">Quiet</ons-button>
                </p>
            </div>
            
            <!-- 操作栏 -->
            <div class="code-actions" onclick="toggleCode('basic-button')">
                <div class="code-actions-left">
                    <ons-icon id="icon-basic-button" icon="md-chevron-down"></ons-icon>
                    <span>查看代码</span>
                </div>
                <div class="code-actions-right">
                    <button class="code-action-btn" id="copy-btn-basic-button" 
                            onclick="event.stopPropagation(); copyCode('basic-button')">
                        <ons-icon icon="md-copy"></ons-icon>
                        <span class="btn-text">复制</span>
                    </button>
                </div>
            </div>
        </div>

        <h3 class="section-title">带图标的按钮</h3>
        
        <div class="code-example-container">
            <div class="code-demo-area">
                <p style="margin: 10px 0;">
                    <ons-button>
                        <ons-icon icon="md-home" style="margin-right: 6px;"></ons-icon>首页
                    </ons-button>
                </p>
                <p style="margin: 10px 0;">
                    <ons-button modifier="cta">
                        <ons-icon icon="md-check" style="margin-right: 6px;"></ons-icon>确认
                    </ons-button>
                </p>
                <p style="margin: 10px 0;">
                    <ons-button modifier="outline">
                        <ons-icon icon="md-favorite" style="margin-right: 6px;"></ons-icon>收藏
                    </ons-button>
                </p>
            </div>
        </div>

        <h3 class="section-title">点击事件</h3>
        
        <div class="code-example-container">
            <div class="code-demo-area">
                <p style="margin: 10px 0;">
                    <ons-button onclick="showToast()">点击显示提示</ons-button>
                </p>
            </div>
        </div>
    </div>

    <script>
        function showToast() {
            ons.notification.toast('按钮被点击了!', {
                timeout: 2000,
                animation: 'fall'
            });
        }
        
        // 切换代码显示
        function toggleCode(id) {
            var codeDisplay = document.getElementById('code-' + id);
            var icon = document.getElementById('icon-' + id);
            
            if (codeDisplay.classList.contains('expanded')) {
                codeDisplay.classList.remove('expanded');
                icon.setAttribute('icon', 'md-chevron-down');
            } else {
                codeDisplay.classList.add('expanded');
                icon.setAttribute('icon', 'md-chevron-up');
            }
        }

        // 复制代码到剪贴板
        function copyCode(id) {
            var codeElement = document.getElementById('code-content-' + id);
            var button = document.getElementById('copy-btn-' + id);
            var buttonText = button.querySelector('.btn-text');
            
            if (!codeElement) return;
            
            var code = codeElement.textContent;
            
            // 使用现代的 Clipboard API
            if (navigator.clipboard && navigator.clipboard.writeText) {
                navigator.clipboard.writeText(code).then(function() {
                    showCopySuccess(button, buttonText);
                }).catch(function() {
                    copyCodeFallback(code, button, buttonText);
                });
            } else {
                copyCodeFallback(code, button, buttonText);
            }
        }
    </script>
</ons-page>

设备信息管理器技术实现深度解析:

DeviceInfoManager类实现了一套完整的设备信息管理和实时监控系统,该系统的设计体现了现代Web应用开发中组件化、模块化的最佳实践。

异步初始化模式: init方法采用了异步初始化模式,通过await this.loadDeviceInfo()确保设备信息加载完成后再进行后续的初始化操作。这种设计避免了因异步操作导致的时序问题,确保了组件的正确初始化。

错误处理策略: loadDeviceInfo方法实现了多层次的错误处理机制。首先通过try-catch捕获JavaScript层面的异常,然后检查原生插件返回的success标志,最后通过showError方法向用户展示友好的错误信息。这种全面的错误处理确保了应用的健壮性。

事件驱动架构: 网络状态监控采用了事件驱动的架构设计,通过window.addEventListener监听原生层推送的网络状态变化事件。这种设计实现了松耦合的组件通信,当网络状态发生变化时,组件能够自动响应并更新界面。

UI状态管理: updateDeviceInfoUIupdateNetworkStatusUI方法实现了精确的UI状态管理,通过DOM操作直接更新界面元素的内容和样式。网络状态指示器通过CSS类名的动态切换实现了视觉状态的变化,为用户提供了直观的状态反馈。

用户体验优化: 系统集成了OnsenUI的通知组件,通过ons.notification.toast为用户提供非侵入式的状态变化提醒。ascend动画效果增强了通知的视觉吸引力,提升了整体的用户体验。

🔄 性能优化实现

实际性能优化系统

项目性能优化策略: 基于项目中的performance-optimizer.js,实现了完整的OnsenUI性能优化系统,包括列表渲染优化、按钮响应优化、以及性能监控等功能。

列表渲染优化实现: 项目采用了Intersection Observer API实现虚拟滚动和延迟加载:

javascript 复制代码
// 项目中的实际列表渲染优化器 - performance-optimizer.js
class ListRenderOptimizer {
    constructor() {
        this.observedLists = new Set();
        this.initIntersectionObserver();
    }

    // 初始化Intersection Observer
    initIntersectionObserver() {
        this.observer = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                const listItem = entry.target;
                
                if (entry.isIntersecting) {
                    this.loadItemContent(listItem);
                } else {
                    this.unloadItemContent(listItem);
                }
            });
        }, {
            rootMargin: '100px 0px', // 提前100px加载
            threshold: 0
        });
    }

    // 加载列表项内容
    loadItemContent(item) {
        if (!item.dataset.loaded) {
            // 延迟加载图片
            const images = item.querySelectorAll('img[data-src]');
            images.forEach(img => {
                img.src = img.dataset.src;
                img.removeAttribute('data-src');
            });
            
            item.dataset.loaded = 'true';
        }
    }

    // 卸载不可见项目的内容以节省内存
    unloadItemContent(item) {
        if (item.dataset.loaded && !this.isInViewport(item)) {
            const images = item.querySelectorAll('img:not([data-src])');
            images.forEach(img => {
                img.dataset.src = img.src;
                img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
            });
            
            item.dataset.loaded = 'false';
        }
    }

    // 优化列表
    optimizeList(listElement) {
        if (this.observedLists.has(listElement)) return;
        
        const items = listElement.querySelectorAll('ons-list-item');
        items.forEach(item => {
            this.observer.observe(item);
        });
        
        this.observedLists.add(listElement);
        console.log(`优化了包含 ${items.length} 个项目的列表`);
    }
}

// 优化的列表更新函数
function updateOnsenUIList(listId, newData) {
    const startTime = performance.now();
    const list = document.getElementById(listId);
    
    if (!list) {
        console.error('列表元素未找到:', listId);
        return;
    }
    
    // 使用DocumentFragment批量操作DOM
    const fragment = document.createDocumentFragment();
    
    // 批量创建新的列表项
    newData.forEach((item, index) => {
        const listItem = document.createElement('ons-list-item');
        listItem.setAttribute('tappable', '');
        
        listItem.innerHTML = `
            <div class="left">
                <ons-icon icon="md-account-circle" class="list-item__icon"></ons-icon>
            </div>
            <div class="center">
                <div class="list-item__title">${item.title}</div>
                <div class="list-item__subtitle">${item.subtitle}</div>
            </div>
            <div class="right">
                <ons-icon icon="md-chevron-right"></ons-icon>
            </div>
        `;
        
        // 添加事件监听
        listItem.addEventListener('click', () => {
            if (typeof itemClicked === 'function') {
                itemClicked(item.title);
            }
        });
        
        fragment.appendChild(listItem);
    });
    
    // 一次性添加到DOM
    list.appendChild(fragment);
    
    const endTime = performance.now();
    console.log(`列表更新完成,耗时: ${(endTime - startTime).toFixed(2)}ms`);
}

// 性能测试套件
function createPerformanceTestSuite() {
    const testResults = [];
    const benchmarks = {
        pageLoad: 300,        // 页面加载时间 < 300ms
        buttonResponse: 50,   // 按钮响应时间 < 50ms
        listRender: 200,      // 列表渲染时间 < 200ms
        frameRate: 55         // 帧率 > 55fps
    };
    
    return {
        // 测试页面切换性能
        async testPageTransition() {
            console.log('测试页面切换性能...');
            const startTime = performance.now();
            
            const navigator = document.getElementById('contentNavigator');
            if (navigator) {
                try {
                    await navigator.resetToPage('cordova_harmonyos_onsui_modules/examples/button.html');
                    const loadTime = performance.now() - startTime;
                    
                    testResults.push({
                        test: 'pageTransition',
                        value: loadTime,
                        passed: loadTime < benchmarks.pageLoad,
                        description: '页面切换性能'
                    });
                    
                    console.log(`页面切换耗时: ${loadTime.toFixed(2)}ms`);
                } catch (error) {
                    console.error('页面切换测试失败:', error);
                }
            }
        },
        
        // 运行所有测试
        async runAllTests() {
            console.log('=== OnsenUI性能测试开始 ===');
            
            await this.testPageTransition();
            
            // 等待所有测试完成
            setTimeout(() => {
                this.generateReport();
            }, 2000);
        },
        
        // 生成测试报告
        generateReport() {
            const passedTests = testResults.filter(test => test.passed).length;
            const totalTests = testResults.length;
            const score = Math.round((passedTests / totalTests) * 100);
            
            console.log('=== 性能测试报告 ===');
            console.log(`总测试数: ${totalTests}`);
            console.log(`通过测试: ${passedTests}`);
            console.log(`性能评分: ${score}分`);
            
            return {
                summary: { total: totalTests, passed: passedTests, score },
                details: testResults
            };
        }
    };
}

数据同步系统技术实现深度解析:

DataSyncManager类实现了一套企业级的数据同步解决方案,该系统在保证数据一致性的同时,最大化了系统的性能和用户体验。

通道管理机制: createSyncChannel方法实现了灵活的同步通道管理,每个通道都有独立的同步间隔、数据变化回调和激活状态。这种设计允许不同类型的数据采用不同的同步策略,例如用户设置可以设置较长的同步间隔,而实时状态数据则需要更频繁的同步。

数据一致性保证: pullDataFromNative方法通过JSON字符串比较来检测数据变化,这种方法虽然简单但非常有效。当检测到数据变化时,系统会触发相应的回调函数,确保Web层能够及时响应数据变化。

性能优化策略: 定期同步机制通过setInterval实现,但每个通道都有独立的lastSync时间戳,避免了不必要的同步操作。这种设计在保证数据实时性的同时,最小化了系统资源的消耗。

错误恢复机制: 每个同步操作都包含完整的错误处理逻辑,当同步失败时,系统会记录错误信息但不会中断其他通道的同步操作。这种设计确保了系统的健壮性和可靠性。

用户偏好同步实现: UserPreferencesSync类展示了数据同步系统的实际应用,通过主题变化的自动应用、UI状态的实时更新等功能,为用户提供了无缝的跨层数据同步体验。

CSS硬件加速优化

项目中的custom-styles.css实现了全面的硬件加速优化:

css 复制代码
/* 项目中的实际硬件加速优化 - custom-styles.css */

/* 工具栏美化 - 添加硬件加速优化 */
ons-toolbar {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    /* 添加硬件加速 */
    transform: translateZ(0);
    will-change: transform;
    transition: box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* 卡片美化 */
ons-card {
    border-radius: 12px;
    box-shadow: 0 2px 12px rgba(0,0,0,0.08);
    border: none;
    margin: 15px 0;
    overflow: hidden;
    /* 添加动画效果 */
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    transform: translateZ(0);
    will-change: transform, box-shadow;
}

ons-card:hover {
    transform: translateY(-2px) translateZ(0);
    box-shadow: 0 8px 24px rgba(0,0,0,0.12);
}

/* 按钮美化 - 添加硬件加速优化 */
ons-button {
    border-radius: 8px;
    font-weight: 500;
    text-transform: none;
    padding: 10px 20px;
    /* 优化过渡效果 */
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    /* 启用硬件加速 */
    transform: translateZ(0);
    will-change: transform, box-shadow;
}

ons-button:active {
    transform: scale(0.98) translateZ(0);
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}

/* 列表美化 - 添加硬件加速优化 */
ons-list {
    background: white;
    border-radius: 12px;
    overflow: hidden;
    margin: 15px 0;
    box-shadow: 0 2px 8px rgba(0,0,0,0.06);
    /* 添加硬件加速 */
    transform: translateZ(0);
}

ons-list-item {
    /* 优化点击动画 */
    transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
    transform: translateZ(0);
    will-change: transform, background-color;
}

ons-list-item:hover {
    background-color: rgba(102, 126, 234, 0.08);
    transform: translateX(2px) translateZ(0);
}

ons-list-item:active {
    background-color: rgba(102, 126, 234, 0.15);
    transform: scale(0.98) translateZ(0);
}

/* 性能优化样式 */

/* 页面切换动画优化 */
ons-page {
    transform: translateZ(0);
    will-change: transform, opacity;
}

/* 图标动画优化 */
ons-icon {
    transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
    transform: translateZ(0);
}

ons-icon:hover {
    transform: scale(1.1) translateZ(0);
}

/* 浮动按钮优化 */
ons-fab {
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    transform: translateZ(0);
    will-change: transform, box-shadow;
}

ons-fab:hover {
    transform: scale(1.1) translateZ(0);
    box-shadow: 0 8px 24px rgba(0,0,0,0.2);
}

/* 通用硬件加速类 */
.hw-accelerated {
    transform: translateZ(0);
    will-change: transform;
}

.smooth-transition {
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* 性能优化工具类 */
.no-select {
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

.gpu-layer {
    transform: translateZ(0);
    backface-visibility: hidden;
    perspective: 1000px;
}

🎯 实战开发经验总结

项目实际开发最佳实践

性能优化实战经验:

  • FPS监控:项目实现了实时FPS监控,当FPS低于55时自动输出性能警告
  • 页面加载优化:页面切换时间控制在100ms以内,超时会提供具体的优化建议
  • 硬件加速应用 :全面使用CSS3的transform: translateZ(0)will-change属性启用GPU加速

OnsenUI组件优化策略:

  • 组件懒加载:使用Intersection Observer API实现列表项的延迟加载
  • 事件优化:为所有按钮添加了涟漪效果和性能监控
  • 内存管理:不可见的列表项会自动卸载图片资源以节省内存

实际项目架构:

  • 16个组件集成:完整实现了Button、List、Dialog、Input、Card等16个OnsenUI组件
  • 分层架构:采用Splitter布局实现左侧导航和右侧内容区域的分离
  • 性能测试:内置完整的性能测试套件,可自动评估应用性能

通过这个实际项目的开发实践,我们验证了OnsenUI在鸿蒙Cordova环境下的完整可行性,为类似项目的开发提供了可靠的技术参考和最佳实践指导。

相关推荐
开开心心_Every6 小时前
Excel图片提取工具,批量导出无限制
学习·pdf·华为云·.net·excel·harmonyos·1024程序员节
爱笑的眼睛117 小时前
深入理解ArkTS类的继承与多态:构建灵活可扩展的HarmonyOS应用
华为·harmonyos
爱笑的眼睛117 小时前
HarmonyOS Toggle开关组件的深度状态管理实践
华为·harmonyos
ChinaDragon8 小时前
HarmonyOS:绘制几何图形 (Shape)
harmonyos
Kisang.8 小时前
【HarmonyOS】ArkWeb——从入门到入土
前端·华为·typescript·harmonyos·鸿蒙
A-刘晨阳10 小时前
《华为数据之道》发行五周年暨《数据空间探索与实践》新书发布会召开,共探AI时代数据治理新路径
人工智能·华为
ChinaDragon11 小时前
HarmonyOS:弹出框蒙层控制
harmonyos
大咖分享课11 小时前
HarmonyOS 6 有哪些新变化、新功能?
华为·harmonyos
EterNity_TiMe_11 小时前
autoconf 工具 OpenHarmony PC 适配指南
华为·harmonyos