• [技术干货] 鸿蒙数据的3种存储方式(Preferences、KV-Store、RelationalStore)
    在选择ArkTs中适合的数据存储方式时,主要考虑以下几个方面:数据类型、数据量、数据同步需求、性能需求以及数据的安全性和可维护性。下面分别说明何时应使用这三种不同的存储方式:1. 用户首选项(Preferences)适用场景:轻量级配置数据的持久化:当应用需要保存用户的一些偏好设置或者轻量级的配置信息时,比如应用的主题、语言选择、用户是否同意某些条款等。不支持分布式同步:如果应用不需要跨设备同步这些配置信息,使用Preferences是非常合适的。需要订阅数据变化:当应用需要实时响应用户偏好或配置的变化时,Preferences提供了数据变化通知的能力,便于实现UI或功能的即时更新。2. 键值型数据管理(KV-Store)适用场景:键值型数据的存储与检索:当应用需要频繁读写简单的键值对数据时,如用户登录状态、临时缓存信息等。分布式同步需求:如果应用需要在不同设备或用户之间同步数据,如用户的登录状态、进度信息等,KV-Store通过DatamgrService提供的分布式同步能力非常有用。高性能与可扩展性:键值型数据库通常具有高性能和可扩展性,适合处理大量的小数据项。数据加密与备份:如果应用对数据安全性有较高要求,或者需要定期备份数据,KV-Store提供的加密和手动备份功能非常有用。3. 关系型数据管理(RelationalStore)适用场景:复杂关系数据的存储:当应用需要存储的数据具有复杂的关系,如用户信息、订单信息、商品信息等,并且这些数据之间存在关联关系时,关系型数据库是更好的选择。需要强事务控制:关系型数据库支持ACID(原子性、一致性、隔离性、持久性)事务,这对于需要强数据一致性和可靠性的应用非常关键。分布式同步需求:类似于KV-Store,RelationalStore也支持通过DatamgrService进行跨设备的数据同步,适合需要同步复杂关系数据的场景。查询性能:关系型数据库提供了丰富的查询能力,支持复杂的SQL查询,这对于需要进行复杂数据分析和报表生成的应用非常有用。总结选择哪种数据存储方式,需要根据应用的具体需求和数据特性来决定。对于轻量级的配置和偏好设置,Preferences是理想的选择;对于简单的键值型数据和需要分布式同步的场景,KV-Store是更好的选择;而对于需要存储复杂关系数据、强事务控制、复杂查询或分布式同步的应用,RelationalStore是更适合的选择。
  • [行业前沿] 【话题交流】鸿蒙和安卓的区别
    鸿蒙NEXT在10月就要上线了,大家来聊聊鸿蒙与安卓的区别
  • [技术干货] 鸿蒙开发常用注解
    在鸿蒙(HarmonyOS)开发中,注解(Annotation)是一种用于描述代码中的信息的元数据,它们不会改变程序的执行流程,但可以用于在编译时或运行时对代码进行解析和操作。鸿蒙开发中常见的注解及其用途包括但不限于以下几点:@Entry:标记一个类作为Ability的入口类,通常用于定义页面的启动。@Component:标记一个类为组件类,可以是页面(Page)、服务(Service)等。@State:在响应式UI框架中,标记类的成员变量为状态变量。当状态变量变化时,界面会重新渲染。@Prop:在自定义组件中,用于接收父组件传递的属性值。@Link:用于组件之间的数据传递和绑定,通常与@Prop配合使用。@Observed:在响应式UI框架中,标记一个类为可观察对象。当类的成员变量变化时,可以通知订阅了该对象的组件。@ObjectLink:标记类的成员变量为跨设备对象链接,通常用于多设备协同场景。@Autowired:自动装配依赖,用于在类中自动注入需要的服务或资源。@RequiresPermission:标记一个方法或类需要特定的权限才能执行。@Syscap:标记系统能力,用于声明能力请求的权限信息,比如访问网络、存储等。@AbilityContext:标记方法的参数,用于从Ability中注入AbilityContext对象。@Subscribe:标记一个方法为事件订阅方法,用于监听和响应特定事件。@Command:标记一个方法为命令方法,通常用于ServiceAbility中,用于响应来自其他Ability的命令。@DataStorage:标记类为数据存储类,用于声明与数据存储相关的配置。@StorageProp:标记类的成员变量为需要自动存储和恢复的属性。@LayoutConfig:用于页面组件,配置页面的布局配置信息。@ContentUri:标记一个字段为内容URI,通常用于媒体文件或文件资源的引用。@Param:标记方法的参数,用于指定参数的类型、名称等信息,常用于路由跳转或事件传递中。@Builder:用于构建模式的注解,可以自动生成构建类的代码。
  • [技术干货] 鸿蒙webview加载的3个性能指标(FCP、FMP、LCP)
    在鸿蒙(HarmonyOS)的WebView组件中,关于网页加载过程的性能指标FCP(First Contentful Paint)、FMP(First Meaningful Paint)和LCP(Largest Contentful Paint)的调用时机和它们之间的区别,可以归纳如下:调用时机FCP(First Contentful Paint)首次内容绘制:调用时机:当页面开始绘制第一个内容元素(如文本、图像、非空白Canvas或SVG)时触发。这是用户首次在视觉上感知到页面加载进度的时刻。目的:衡量页面加载的早期性能,标识页面开始渲染的时间点。FMP(First Meaningful Paint)首次有效绘制:调用时机:比FCP更晚,当页面主要内容开始出现在屏幕上时触发。这通常标志着页面达到了一个用户认为“有用”或“可交互”的状态。目的:衡量页面加载到用户认为可交互状态所需的时间,虽然这个指标的精确性可能因页面内容和用户感知而异。LCP(Largest Contentful Paint)最大内容绘制:调用时机:在可视区域内,页面上的最大内容元素(如图片、视频或文本块)开始出现在屏幕上时触发。这通常反映了页面加载的完成度和用户视觉上的主要关注点。目的:评估页面加载的最终性能和用户体验,特别是针对包含大量视觉元素的页面。它们之间的区别性能指标调用时机主要关注点FCP页面开始绘制第一个内容元素时衡量页面加载的早期性能,用户首次感知到加载进度的时刻FMP页面主要内容开始出现在屏幕上时衡量页面加载到用户认为可交互状态所需的时间,尽管精确性可能因页面和用户而异LCP可视区域内最大内容元素开始出现在屏幕上时评估页面加载的最终性能和用户体验,特别是针对视觉元素丰富的页面在鸿蒙WebView组件中,这些性能指标通常通过特定的事件或回调函数来通知开发者,如onFirstContentfulPaint、onFirstMeaningfulPaint和onLargestContentfulPaint。这些回调函数的调用时机与上述描述的调用时机相对应,允许开发者在WebView加载网页的过程中,监控并优化页面的加载性能和用户体验。请注意,由于鸿蒙系统的不断发展和更新,具体的API接口和性能指标的细节可能会有所变化。因此,建议开发者参考最新的鸿蒙系统文档和API指南以获取最准确的信息。
  • [技术干货] 鸿蒙中的FA模型和Stage模型
    鸿蒙系统中的FA模型和Stage模型是两种不同的应用开发模型,它们在设计思想、组件类型、资源共享和内存占用、系统管理和控制能力,以及模型演进和主推程度等方面存在显著的差异。FA模型FA模型是“Feature Ability”(功能能力)的缩写,是HarmonyOS早期版本开始支持的模型。该模型基于微内核架构,通过IPC(进程间通信)和分布式软总线完成轻量化、松耦合的模块间通信和服务调用。其主要特点包括:分布式调度:支持分布式调度,具有实时计算和交互控制的特性。独立引擎实例:每个应用组件独享一个ArkTS引擎实例,没有实现组件间的资源共享和内存优化。系统管理能力:在系统管理和控制能力方面,FA模型没有像Stage模型那样强调对后台进程的有序治理和严格管理。Stage模型Stage模型是HarmonyOS 3.1及后续版本主推且会长期演进的模型,它提供了一种更好的开发方式,更适用于多设备、分布式场景。Stage模型的主要特点包括:组件共享:多个应用组件共享同一个ArkTS引擎实例,使得应用组件之间可以方便地共享对象和状态,同时减少复杂应用运行对内存的占用。多窗口管理:Stage模型将应用的界面划分为多个独立的Stage,每个Stage都有自己的窗口和界面布局,可以单独显示、隐藏和关闭。不同的Stage之间可以进行切换和互动,提供了更加丰富的用户交互方式。组件类型:提供UIAbility和ExtensionAbility两种类型的组件。UIAbility组件用于与用户交互,而ExtensionAbility组件则提供场景化的服务扩展机制,但不提供自定义服务的能力。生命周期管理:UIAbility组件的生命周期包含创建、销毁、前台、后台状态,与界面强相关的获焦、失焦状态都放在窗口管理对象中,实现与窗口之间的弱耦合。系统管理能力:对后台应用进程进行了有序治理,应用程序不能随意留驻在后台,同时应用后台行为受到严格管理,以防止恶意应用行为。总结FA模型和Stage模型在鸿蒙系统中各有其应用场景和优势。FA模型更适合于需要高度独立性和轻量级通信的场景,而Stage模型则更适用于多设备、分布式场景下的复杂应用开发。随着HarmonyOS的不断演进,Stage模型将成为未来应用开发的主流方向。开发者在选择使用哪种模型时,应根据具体的应用需求、系统环境和技术要求进行综合考虑。
  • [获奖公告] 【开发者日专场】产品体验官:仓颉鸿蒙应用开发初体验
    华为云开发者日·上海站来啦!参加“仓颉鸿蒙应用开发初体验”体验项目提出你的建议或使用体验有机会获得开发者盲盒礼包惊喜不容错过,快叫上小伙伴一起来参加吧~【体验项目】仓颉鸿蒙应用开发初体验【活动时间】2024年8月30日-9月6日【参与方式】直接在此活动帖下方回帖提建议/提建议即可比如对产品功能的改进建议、对活动流程的感想、对现场活动的感悟等等PS:不要少于30字哦~【获奖规则】奖项设置有效回复楼层评选条件获奖名额激励礼品优质建议奖20对产品功能有改进价值的建议1名开发者盲盒礼品价值50-100元积极反馈奖20优质建议奖轮空的情况下进行抽取抽取1名开发者盲盒礼品价值50元【活动规则】1、本帖的回帖建议不少于30字,仅限于对“仓颉鸿蒙应用开发初体验”体验项目,其他项目建议不参与此次活动,否则将视为无效内容。2、本次活动将根据实际参与情况发放奖励,包括但不限于用户百分之百中奖或奖项轮空的情况;以上奖品均为实物奖品,具体发放视出库情况而定;3、活动预计于结束后七天内完成奖项公示,并于结束后15个工作日内完成邮寄。【温馨提示】1、请务必使用个人实名账号参与活动(IAM、企业账号等账号参与无效)。如一个实名认证对应多个账号,只有一个账号可领取奖励,若同一账号填写多个不同收件人或不同账号填写同一收件人,均不予发放奖励。2、所有获得奖品的获奖用户,请于获奖后3日内完成实名认证,否则视为放弃奖励。
  • [分享交流] 产教融合专家大讲堂·第②期官网直播平台获奖用户名单公示
    产教融合专家大讲堂·第②期官网直播平台获奖用户名单公示:185****8920157****7269139****2457189****3693在直播过程中,被讲师选中的优质问题如下:您认为校企合作在人才培养创新中优势有哪些?在咱们学校,是怎样结合学校的优势,来推动校企合作的人才培养?【请以上获奖嘉宾在8月29号18点前填写问卷反馈获奖的个人收货信息,方便我们发放礼品,过期不候!】https://survey.huaweicloud.com/survey/#/qtn?id=2bfde47aa0c64f658df5295f8c128075//////////////////////////////////​“产教融合专家大讲堂”系列直播活动第二期来啦,本期主题为““校企合作·协同育人”人培模式探索与实践分享”,我们邀请到了山东科技职业学院 物联网应用技术专业主任王延亮、郑州电力高等专科学校 信息通信学院院长冯明卿、山东信息职业技术学院 软件与大数据系主任武洪萍,为大家分享《深化产教融合共同体合作,画好产教融合、校企合作同心圆》、《行业高职院校信创人才培养的探索与实践》、《科教融汇 协同创新 产教深度融合的软件与大数据专业群建设》三大议题。直播链接:https://bbs.huaweicloud.com/live/edu_live/202408261600.html直播时间:8月26日(星期一)16:00-18:00福利1:发送口令,参与抽奖官网以及视频号直播间发口令“校企合作”,抽手持便携风扇。注:官网随机抽取3名,视频号随机抽取3名。官网直播链接:https://bbs.huaweicloud.com/live/edu_live/202408261600.html视频号直播链接:请扫描上图二维码。福利2:有奖提问直播过程中,每位直播讲师会评选1个优质问题送便携水杯。欢迎大家踊跃提问~名额有限。【请获奖嘉宾在8月29号18点前在官网以及视频号平台私信反馈获奖的个人收货信息,方便我们发放礼品,过期不候!】
  • [技术干货] 鸿蒙 arkui 中的 UIContext 和 UIAbilityContext
    在鸿蒙(HarmonyOS)的ArkUI框架中,UIContext 和 UIAbilityContext 是两个与上下文环境相关的概念,它们在应用开发中扮演着不同的角色。以下是对这两个概念的详细解释及区别:定义UIContext定义: UIContext 是ArkUI框架中用于管理UI组件上下文的一个对象。它提供了一系列与UI渲染、动画、弹窗显示等相关的接口,允许开发者在UI组件的上下文中执行特定的操作。UIContext 对象通常与具体的UI页面或组件实例相关联,用于处理该页面或组件内的UI逻辑。功能:UI渲染:管理UI组件的渲染和布局。动画处理:提供动画相关的接口,如animateTo,用于在UI元素之间添加过渡动画。弹窗显示:通过showAlertDialog、showActionSheet等方法显示警告弹窗或列表弹窗。来源: UIContext 对象是ArkUI框架的一部分,由ArkUI框架在创建UI页面或组件时自动管理和提供。UIAbilityContext定义: UIAbilityContext 是继承自Context的一个特殊上下文环境,专门用于UI Ability(即用户界面能力)中。它提供了操作UI Ability所需的各种接口,包括启动其他Ability、获取配置信息、申请权限等。功能:Ability操作:提供启动、停止Ability的能力。配置信息获取:允许开发者获取当前UI Ability的配置信息。权限申请:支持应用向用户申请必要的权限。资源访问:访问特定于UI Ability的资源。来源: UIAbilityContext 是鸿蒙应用开发框架中的一部分,每个UI Ability在创建时都会获得一个与之关联的UIAbilityContext对象。区别作用范围:UIContext 主要用于管理UI组件的上下文,包括渲染、动画、弹窗等UI相关的操作。UIAbilityContext 则更侧重于UI Ability级别的操作,如启动其他Ability、获取配置信息、申请权限等。提供的功能:UIContext 提供的功能更加聚焦于UI层面的细节处理。UIAbilityContext 提供的功能则更加宏观,涉及到Ability的生命周期管理、资源访问等。关联对象:UIContext 通常与具体的UI页面或组件实例相关联。UIAbilityContext 则与UI Ability相关联,是UI Ability的上下文环境。总结来说,UIContext 和 UIAbilityContext 在鸿蒙ArkUI框架中分别扮演着UI组件上下文管理和UI Ability上下文管理的角色,它们在作用范围、提供的功能以及关联对象上存在差异。开发者在开发过程中应根据具体需求选择合适的上下文环境来执行相应的操作。
  • [分享交流] OpenHarmony 兼容性认证介绍
    注附件ppt为兰州大学2024年2022级人工智能暑期学校暨华为开发者布道师活动的部分讲义PPT备注首先,先简要介绍一下OpenHarmony。OpenHarmony是一个开源项目,是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的,它的代码仓部署在gitee上。然后不同公司组织可以基于这个开源项目,开发自己的商用设备、发行版等产品。最后既然它是一个开源项目,就需要一个具有活力的开发者社区,所以我们可以看到这些指标中有一个社区贡献者5100+的数据。然后我将从什么是兼容性测试、为什么要进行兼容性测试、以及兼容性测试的流程 这三个方面进行介绍,也就是What、Why、How,首先是What。刚才我们提到了OpenHarmony是一个开源项目,其次OpenHarmony也是一个操作系统,它针对不同性能需求的设备定义了三种基础系统类型:轻量系统、小型系统、标准系统。区分这三种类型的一个最主要的指标就是,设备支持内存的大小。轻量系统设备的最小内存为128KB,例如一些传感器、穿戴类设备等;小型系统设备的最小内存为1MB,一些比较典型的产品比如电子猫眼、路由器以及行车记录仪等;而标准系统设备的最小内存为128MB,例如冰箱显示屏以及我们前一段时间做的水质监测设备,这些设备需要更强的图形交互能力以及完整的应用框架。在我们进行OpenHarmony应用以及设备的开发时,需要根据实际需求选择这三种系统类型之一。兼容性认证主要分为两项内容:第一项是向兼容性工作组提交兼容性规范自测表,这张图展示了一部分填写内容;兼容性认证的第二项内容是提交XTS测试报告,包括应用兼容性测试、分布式兼容性测试、系统安全漏洞测试等共计五项测试,而每项测试包含若干个模块。进行每项测试需要从OH官网获取测试套件,比如你将测试代码放到个人PC,然后将OpenHarmony设备与PC连接,再通过命令行启动测试框架就可以了。接下来介绍 “为什么需要兼容性认证”在2024年的今天,我们生活中常见的智能终端是多种多样的,手机、电脑、智能手表、等等。到2025年,预计人均持有的智能终端设备(比如手机、电脑、智能手表等)将超过9台。然而,更多的设备并没有带来更好的全场景体验。设备之间的连接复杂,生态无法共享,数据难以互通。系统的碎片化从底层制约了万物互联时代的业务创新,亟需一个统一的解决方案。既然智能终端领域存在这么一些问题,华为给出的解决方案就是在各种终端使用同一个操作系统——也就是鸿蒙,并且对鸿蒙生态的展望是:构建一个万物互联的智能世界,这种统一的生态具有两个关键特征:第一:每个APP只需开发、维护一套代码、第二:APP之间跨设备流转方便快捷。
  • [技术干货] 鸿蒙多个BuilderParam传递UI
    在鸿蒙(HarmonyOS)开发中,如果你遇到需要传递多个BuilderParam(尽管在鸿蒙官方API中可能并不直接存在名为BuilderParam的类,这里我假设你是在类比其他框架中的构建器参数模式)来配置UI组件的情况,你通常会通过自定义构建器(Builder)模式来实现这一点。鸿蒙系统的UI开发通常基于XML布局文件和Java/Kotlin/eTS(对于鸿蒙应用来说)代码。但是,为了动态创建和配置UI组件,并传递多个参数,你可以定义自己的构建器类。以下是一个假设的例子,展示了如何定义一个构建器类来创建和配置一个自定义的UI组件,并传递多个参数:// 假设这是你的自定义UI组件 public class MyCustomComponent extends Component { // 组件的属性 private String text; private int color; private boolean isEnabled; // 私有构造函数,防止外部直接实例化 private MyCustomComponent() {} // 构建器类 public static class Builder { private MyCustomComponent component; public Builder() { component = new MyCustomComponent(); } // 链式方法设置text public Builder setText(String text) { component.text = text; return this; } // 链式方法设置color public Builder setColor(int color) { component.color = color; return this; } // 链式方法设置isEnabled public Builder setEnabled(boolean isEnabled) { component.isEnabled = isEnabled; return this; } // 最终构建方法,返回配置好的组件 public MyCustomComponent build() { // 这里可以添加一些额外的初始化代码,如果需要的话 return component; } } // 假设这里有一些方法来渲染或处理这个组件... } // 使用方式 MyCustomComponent myComponent = new MyCustomComponent.Builder() .setText("Hello, HarmonyOS!") .setColor(Color.BLUE) .setEnabled(true) .build(); // 接下来,你可以将这个组件添加到你的布局中 // 注意:这里的添加到布局的具体方法取决于你的应用结构和鸿蒙的API // 假设有一个方法叫addToLayout,它负责将组件添加到UI中 // addToLayout(myComponent);请注意,上面的代码示例是基于Java的,但如果你在使用eTS(鸿蒙的TypeScript扩展),你将以类似的方式定义类和构建器,但语法会有所不同。在鸿蒙系统中,通常你不需要直接处理像BuilderParam这样的参数对象,因为构建器模式本身就已经通过链式调用方法优雅地处理了参数的传递。如果你确实需要传递一个包含多个属性的复杂对象,你可以定义一个数据类(在Java中是一个普通的类,在eTS中可能是一个接口或类型别名)来封装这些属性,并在构建器中使用这个数据类作为参数。然而,在大多数情况下,直接在构建器中定义方法以接收每个参数会更加直观和方便。
  • [技术干货] 鸿蒙 @prop 父向子单向传递
    在鸿蒙(HarmonyOS)开发中,组件之间的数据传递是一个常见的需求,尤其是父组件向子组件的单向数据传递。然而,需要注意的是,鸿蒙开发中并没有一个直接名为@prop的注解或特性来专门用于数据传递,这是在其他一些前端框架(如Vue.js)中常见的做法。不过,鸿蒙提供了自己的方式来处理组件间的数据传递,通常是通过组件的属性和方法来实现的。在鸿蒙开发中,你可以通过定义组件的自定义属性(Properties)来实现父组件向子组件的单向数据传递。这些属性可以在子组件的XML布局文件中通过ohos:attr来设置(如果属性是预定义的),或者更常见的是,在父组件的Java/Kotlin/eTS代码中通过调用子组件的setter方法来设置。以下是一个简单的例子来说明如何在鸿蒙中实现父组件向子组件的单向数据传递:子组件(MyChildComponent.java/MyChildComponent.ets)首先,定义一个子组件,它有一个自定义属性(在这个例子中,我们直接在代码中处理,而不是在XML中声明):// 假设这是Java代码 public class MyChildComponent extends Component { private String customData; // 自定义的setter方法 public void setCustomData(String customData) { this.customData = customData; // 在这里,你可以根据customData的值来更新UI或其他逻辑 } // 组件的其他部分... }如果是eTS代码,可能会是这样的:// MyChildComponent.ets @Entry @Component struct MyChildComponent { private customData: string = ''; // 自定义的setter方法(在eTS中通常不需要显式定义setter,但可以通过方法或属性绑定来更新) updateCustomData(newData: string) { this.customData = newData; // 更新UI或其他逻辑 } // 组件的UI部分... build() { // 使用customData来构建UI // ... } }父组件然后,在父组件中,你通过获取子组件的引用并调用其setter方法来传递数据:// 假设这是Java代码 public class MyParentComponent extends Component { private MyChildComponent childComponent; @Override protected void onFinishInflate() { super.onFinishInflate(); // 假设你已经通过某种方式(如findComponentById)获取了childComponent的引用 childComponent.setCustomData("这是从父组件传递的数据"); } // 父组件的其他部分... }在eTS中,你可能会在父组件的某个方法中设置数据,如果子组件是通过属性或插槽传递的,你可以直接在子组件上调用方法:// MyParentComponent.ets @Entry @Component struct MyParentComponent { @State childData: string = '这是从父组件传递的数据'; // 假设childComponent是通过某种方式(如@Link或@Ref)获取的 childComponent: MyChildComponent | null = null; updateChildData() { if (this.childComponent) { this.childComponent.updateCustomData(this.childData); } } // 父组件的UI部分和逻辑... build() { // ... } }请注意,上面的eTS代码示例中的@State、@Link和@Ref是假设的装饰器,用于说明目的。在鸿蒙的eTS中,你可能需要使用不同的机制来获取子组件的引用或更新状态。实际上,鸿蒙的eTS框架提供了自己的状态管理和组件通信机制,如@State用于状态管理,但获取子组件引用和调用其方法可能需要通过不同的方式来实现,如通过ref属性获取DOM引用(但请注意,这通常用于原生元素或自定义组件的根元素,而不是直接调用组件的方法)。在鸿蒙的组件化开发中,更常见的做法是通过事件监听和派发来实现组件间的通信。
  • [技术干货] 鸿蒙builderParam构建函数-传递UI
    在鸿蒙(HarmonyOS)开发中,builderParam 通常不是一个直接用于构建 UI 的标准术语或API。不过,基于你的描述,我猜测你可能是在询问如何在鸿蒙系统中通过某种方式(可能是通过自定义的 Builder 模式或类似的构造器模式)来构建和传递 UI 参数。在鸿蒙系统中,UI 的构建主要通过 XML 布局文件和 Java/Kotlin(对于 HarmonyOS 应用开发来说,实际上是 Java/JavaScript/eTS - Extensible TypeScript)代码来实现。但是,为了回答你的问题,我可以提供一个基于“构建器模式”(Builder Pattern)的概念性示例,用于在代码中动态构建和传递 UI 组件的参数。示例:使用构建器模式构建 UI 组件假设我们有一个自定义的 UI 组件(比如一个自定义的 Button),并且我们希望通过构建器模式来设置它的属性。public class CustomButton { private String text; private int color; private int size; // 私有构造函数 private CustomButton() {} // 静态内部类作为构建器 public static class Builder { private CustomButton button; public Builder() { button = new CustomButton(); } public Builder setText(String text) { button.text = text; return this; } public Builder setColor(int color) { button.color = color; return this; } public Builder setSize(int size) { button.size = size; return this; } // 最终构建并返回 CustomButton 实例 public CustomButton build() { return button; } } // 假设有一些方法来展示或处理这个按钮... } // 使用方式 CustomButton button = new CustomButton.Builder() .setText("点击我") .setColor(Color.RED) .setSize(24) .build(); // 假设这里有一个方法来将 button 添加到 UI 中 // addButtonToUI(button);鸿蒙 UI 组件的创建和配置实际上,在鸿蒙系统中,UI 组件的创建和配置主要通过 XML 布局文件来定义,并且可以在 Java/Kotlin/eTS 代码中通过组件的 API 进行进一步的配置。如果你需要在代码中动态创建 UI 组件,你可以使用组件的构造函数或工厂方法来创建实例,并通过其 setter 方法或属性来配置。结论虽然 builderParam 不是鸿蒙系统中的一个直接概念,但你可以通过实现构建器模式(Builder Pattern)来在代码中构建和配置 UI 组件。鸿蒙系统提供了丰富的 API 来在代码中操作 UI 组件,包括创建、配置和布局等。如果你的 UI 构建逻辑非常复杂,使用构建器模式可以帮助提高代码的可读性和可维护性。
  • [技术干货] 鸿蒙采用TS而非Java的原因
    鸿蒙开发官方选择ArtTS(也称为ArkTS)作为主力应用开发语言,而不是Java、Kotlin或安卓传统开发语言,主要基于以下几个方面的考虑:1. 继承与扩展TypeScript的优势TypeScript(TS)基础:ArtTS在TypeScript的基础上进行了扩展,继承了TS的所有特性,并增加了声明式UI、状态管理等能力。这使得ArtTS在语法结构上与JavaScript相似,但在功能上更为强大。静态类型系统:ArtTS对TS的动态类型特性施加了更严格的约束,引入了静态类型,提高了代码的可读性和可维护性。2. 简洁高效的开发体验声明式UI:ArtTS提供了声明式UI的能力,开发者可以直观地描述UI,无需关心具体的UI绘制和渲染过程,从而提高了开发效率。状态管理:ArtTS内置了多维度的状态管理机制,使得与UI相关联的数据可以在组件间灵活传递,实现了数据和UI的联动。3. 跨平台适配能力统一UI后端引擎:ArtTS通过统一的UI后端引擎,提供了一套页面渲染的指令,实现了对不同系统的跨平台适配。这使得开发者可以更加灵活地开发跨端应用。方舟编译器支持:方舟编译器将ArtTS编写的代码编译成字节码和机器码,提高了运行效率。同时,将转译动作从运行期提前到编译期,进一步提升了性能。4. 华为生态战略考量独立生态建设:华为在鸿蒙系统建设初期就决心打造一个独立的生态系统,而不是仅仅依赖Android应用的兼容。因此,选择ArtTS作为主力开发语言,有助于在JavaScript生态基础上建立华为的应用生态。技术趋势洞察:随着5G、物联网等技术的快速发展,设备间的互联互通变得越来越重要。JavaScript作为一种通用语言,能够很好地适应这种趋势,实现跨平台、跨设备的无缝对接。5. 开发者友好性降低学习成本:对于熟悉TypeScript的开发者来说,学习ArtTS相对容易。这使得开发者可以更快地投入到鸿蒙应用的开发中。提高开发效率:ArtTS的简洁语法和强大功能使得开发者能够更高效地完成应用开发任务。综上所述,鸿蒙开发选择ArtTS作为官方语言是基于其继承TypeScript的优势、提供简洁高效的开发体验、具备跨平台适配能力、符合华为生态战略考量以及降低开发者学习成本等多方面因素的综合考虑。这些优势使得ArtTS成为鸿蒙应用开发的首选语言。
  • [技术交流] rk3568使用napi进行uart串口开发,遇到问题。
    rk3568使用uart进行串口通信代码实现,napi代码如下#include "napi/native_api.h"#include "platform_if.h"#include "uart_if.h"#include "hdf_base.h"#include <cstdint>#include "hdf_types.h"#include <cstdlib>#include <functional>#include <hilog/log.h>#include <js_native_api_types.h>static napi_value Add(napi_env env, napi_callback_info info){ size_t argc = 2; napi_value args[2] = {nullptr}; napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); napi_valuetype valuetype0; napi_typeof(env, args[0], &valuetype0); napi_valuetype valuetype1; napi_typeof(env, args[1], &valuetype1); double value0; napi_get_value_double(env, args[0], &value0); double value1; napi_get_value_double(env, args[1], &value1); napi_value sum; napi_create_double(env, value0 + value1, &sum); return sum;}unsigned long open(char port[50]) { return open(port); }static napi_value UartOpen(napi_env env, napi_callback_info info){ size_t requireArgc = 1; size_t argc = 1; napi_value args[1] = {nullptr}; napi_get_cb_info(env, info,&argc,args ,nullptr, nullptr); napi_valuetype valuetype0; napi_typeof(env,args[0], &valuetype0); size_t size; char port[50] ; napi_get_value_string_utf8(env, args[0], port, 50, &size); size_t ret; ret = open(port); if (ret == NULL) { HDF_FAILURE; } }unsigned long setAttribute(char port, char attribute) { setAttribute(port, attribute); }static napi_value UartSetAttribute(napi_env env , napi_callback_info info){ size_t requireArgc = 2; size_t argc = 2; napi_value args[2] = {nullptr}; napi_get_cb_info(env, info,&argc,args ,nullptr, nullptr); napi_valuetype valuetype0; napi_typeof(env,args[0], &valuetype0); napi_valuetype valuetype1; napi_typeof(env,args[0], &valuetype1); char port{50}; size_t size; size_t ret; struct UartAttribute attribute; attribute.dataBits = UART_ATTR_DATABIT_8; attribute.parity = UART_ATTR_PARITY_NONE; attribute.stopBits = UART_ATTR_STOPBIT_1; // UART传输数据停止位为1位 attribute.rts = UART_ATTR_RTS_DIS; // UART禁用RTS attribute.cts = UART_ATTR_CTS_DIS; // UART禁用CTS attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; // UART使能RX FIFO attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; // UART使能TX FIFO ret = UartSetAttribute(&port, &attribute); if (ret != HDF_SUCCESS) { LOG_ERROR; } LOG_INFO;} struct napi_value__ * write(int port, unsigned long data) {return write(port, data);}static napi_value UartWrite(napi_env env , napi_callback_info info){ size_t requireArgc = 2; size_t argc = 2; napi_value args[2] = {nullptr}; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); napi_valuetype valuetype0; napi_typeof(env, args[0], &valuetype0); napi_valuetype valuetype1; napi_typeof(env, args[1], &valuetype1); int32_t port; DevHandle handle = UartOpen(port); napi_get_value_int32(env, args[0], &port); napi_get_value_int32(env, args[0], &port); char value0[50]; size_t data; napi_get_value_string_utf8(env, args[1], value0, 50, &data); int32_t size; size = sizeof(data); napi_value ret;ret = write(port,data); napi_create_int32(env, data,&ret ); return ret; if (ret == NULL) { LOG_ERROR; }return ret;} struct napi_value__ * read(int port, char data[512]) { return read(port, data); }static napi_value UartRead(napi_env env , napi_callback_info info){ size_t requireArgc = 2; size_t argc = 2; napi_value args[2] = {nullptr}; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); napi_valuetype valuetype0; napi_typeof(env, args[0], &valuetype0); napi_valuetype valuetype1; napi_typeof(env, args[1], &valuetype1); int32_t port; napi_get_value_int32(env, args[0], &port); char value0[50]; size_t data; napi_get_value_string_utf8(env, args[1], value0, 50, &data); napi_value ret; ret = read(port,value0); napi_create_int32(env, data,&ret ); return ret; if (ret == NULL) { LOG_ERROR; }return ret;}struct napi_value__ * set(char port[50], unsigned int BaudRate) { return set(port, BaudRate);}static napi_value UartSetBaud(napi_env env, napi_callback_info info){ size_t requireArgc = 2; size_t argc = 2; napi_value args[2] = {nullptr}; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); napi_valuetype valuetype0; napi_typeof(env, args[0], &valuetype0); napi_valuetype valuetype1; napi_typeof(env, args[1], &valuetype1); char port[50]; size_t size1; napi_get_value_string_utf8(env, args[0], port, 50, &size1); int32_t BaudRate ; BaudRate= 150000; napi_value result; napi_create_int32(env, 1500000,&result); napi_value ret; ret = set(port,15000000); if (ret == NULL ) { HDF_FAILURE; } return ret; } struct napi_value__ * get(char port[50], int BaudRate) { return get(port, BaudRate);}static napi_value UartGetBaud(napi_env env, napi_callback_info info){ size_t requireArgc = 2; size_t argc = 2; napi_value args[2] = {nullptr}; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); napi_valuetype valuetype0; napi_typeof(env, args[0], &valuetype0); napi_valuetype valuetype1; napi_typeof(env, args[1], &valuetype1); char port[50]; size_t size1; napi_get_value_string_utf8(env, args[0], port, 50, &size1); int32_t BaudRate; napi_value ret; napi_create_int32(env, BaudRate, &ret); napi_create_int32(env, size1, &ret); ret = get(port, BaudRate); if (ret == nullptr) { HDF_FAILURE;; } return ret; }struct napi_value__ * close(int port) { return close(port);}static napi_value UartClose(napi_env env, napi_callback_info info){ size_t requireArgc = 1; size_t argc = 1; napi_value args[1] = {nullptr}; napi_get_cb_info(env, info,&argc,args ,nullptr, nullptr); napi_valuetype valuetype0; napi_typeof(env,args[0], &valuetype0); int port; napi_get_value_int32(env, args[0], &port); close(port); napi_value ret; napi_create_int32(env, port, &ret); if (ret == NULL) { HDF_FAILURE; }return ret;}EXTERN_C_STARTstatic int32_t UartTest(void ) { int32_t ret; uint32_t port; uint32_t baud = 15000000; DevHandle handle = NULL; uint8_t wbuff[] = {}; uint8_t rbuff[] = {}; struct UartAttribute attribute; attribute.dataBits = UART_ATTR_DATABIT_8; // UART传输数据位宽,一次传输8个bit attribute.parity = UART_ATTR_PARITY_NONE; // UART传输数据无校检 attribute.stopBits = UART_ATTR_STOPBIT_1; // UART传输数据停止位为1位 attribute.rts = UART_ATTR_RTS_DIS; // UART禁用RTS attribute.cts = UART_ATTR_CTS_DIS; // UART禁用CTS attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; // UART使能RX FIFO attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN;// UART使能TX FIFO ret = UartSetAttribute(handle, &attribute); handle = UartOpen(port); if (ret != HDF_SUCCESS) { return HDF_FAILURE; } ret = UartSetBaud(handle, 1500000); if (ret != HDF_SUCCESS) { return HDF_FAILURE; } ret = UartGetBaud(handle, &baud); if (ret != HDF_SUCCESS) { return HDF_FAILURE; } ret = UartWrite(handle, wbuff, sizeof(wbuff)); if (ret != HDF_SUCCESS) { return HDF_FAILURE; } ret = UartRead(handle, rbuff, sizeof(rbuff)); if (ret != HDF_SUCCESS) { return HDF_FAILURE; } UartClose(handle); if (ret != HDF_SUCCESS) { return HDF_FAILURE; } return HDF_SUCCESS;}static napi_value Init(napi_env env, napi_value exports){ napi_property_descriptor desc[] = { { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }, { "UartOpen", nullptr, UartOpen, nullptr, nullptr, nullptr, napi_default, nullptr }, { "UartClose", nullptr, UartClose, nullptr, nullptr, nullptr, napi_default, nullptr }, { "UartWrite", nullptr, UartWrite, nullptr, nullptr, nullptr, napi_default, nullptr }, { "UartRead", nullptr, UartRead, nullptr, nullptr, nullptr, napi_default, nullptr }, { "UartSetBaud", nullptr, UartSetBaud, nullptr, nullptr, nullptr, napi_default, nullptr }, { "UartGetBaud", nullptr, UartGetBaud, nullptr, nullptr, nullptr, napi_default, nullptr } }; napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); return exports;}EXTERN_C_ENDstatic napi_module demoModule = { .nm_version = 1, .nm_flags = 0, .nm_filename = nullptr, .nm_register_func = Init, .nm_modname = "entry", .nm_priv = ((void*)0), .reserved = { 0 },};extern "C" __attribute__((constructor)) void RegisterEntryModule(void){ napi_module_register(&demoModule);}cmakelist.txt内容如下:# the minimum version of CMake.cmake_minimum_required(VERSION 3.4.1)project(Uart)if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a")endif()if (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/path/to/openharmony/libs")endif()set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})SET (CMAKE_BUILD_TYPE Debug CACHE INTERNAL “” FORCE)if(DEFINED PACKAGE_FIND_FILE) include(${PACKAGE_FIND_FILE})endif()include_directories(${NATIVERENDER_ROOT_PATH} ${NATIVERENDER_ROOT_PATH}/include)add_library(entry SHARED napi_init.cpp) target_link_libraries(serialhelper PUBLIC libace_napi.z.so libc++.a libhilog_ndk.z.so libuv.so libserialport_service_api.z.so)运行工程报错: > hvigor ERROR: Failed :entry:default@BuildNativeWithCmake...  > hvigor ERROR: Exceptions happened while executing: Not searching for unused variables given on the command line. -- The CXX compiler identification is unknown CMake Error at CMakeLists.txt:3 (project):   The CMAKE_CXX_COMPILER:      C:/Program Files/Huawei/DevEco Studio/license/DevEco Studio/sdk/HarmonyOS-NEXT-DB1/openharmony/native/llvm/bin/clang++.exe    is not a full path to an existing compiler tool.    Tell CMake where to find the compiler by setting either the environment   variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path   to the compiler, or to the compiler name if it is in the PATH.  -- Configuring incomplete, errors occurred! See also "C:/Users/Administrator/DevEcoStudioProjects/Uart/entry/.cxx/default/default/arm64-v8a/CMakeFiles/CMakeOutput.log". See also "C:/Users/Administrator/DevEcoStudioProjects/Uart/entry/.cxx/default/default/arm64-v8a/CMakeFiles/CMakeError.log".  > hvigor ERROR: BUILD FAILED in 2 s 908 ms  hilog中报错如下:08-05 17:28:11.725   5162-5162    C02f00/teecd                   pid-5162              E     open tee client dev failed, fd is <private> 08-05 17:28:11.726   5162-5162    C02f00/teecd                   pid-5162              E     fs agent init failed 08-05 17:28:11.726   5162-5162    C02f00/teecd                   pid-5162              E     open tee client dev failed, fd is <private> 08-05 17:28:11.726   5162-5162    C02f00/teecd                   pid-5162              E     misc agent init failed 08-05 17:28:11.750   5163-5163    C02f00/teecd                   pid-5163              E     open tee client dev failed, fd is <private> 08-05 17:28:11.750   5163-5163    C02f00/teecd                   pid-5163              E     fs agent init failed 08-05 17:28:11.750   5163-5163    C02f00/teecd                   pid-5163              E     open tee client dev failed, fd is <private> 08-05 17:28:11.750   5163-5163    C02f00/teecd                   pid-5163              E     misc agent init failed 08-05 17:28:11.768   5164-5164    C02f00/teecd                   pid-5164              E     open tee client dev failed, fd is <private> 08-05 17:28:11.768   5164-5164    C02f00/teecd                   pid-5164              E     fs agent init failed 08-05 17:28:11.769   5164-5164    C02f00/teecd                   pid-5164              E     open tee client dev failed, fd is <private> 08-05 17:28:11.769   5164-5164    C02f00/teecd                   pid-5164              E     misc agent init failed 08-05 17:28:11.784   5165-5165    C02f00/teecd                   pid-5165              E     open tee client dev failed, fd is <private> 08-05 17:28:11.784   5165-5165    C02f00/teecd                   pid-5165              E     fs agent init failed 08-05 17:28:11.784   5165-5165    C02f00/teecd                   pid-5165              E     open tee client dev failed, fd is <private> 08-05 17:28:11.784   5165-5165    C02f00/teecd                   pid-5165              E     misc agent init failed 08-05 17:28:14.679   547-866      C01719/ffrt                    foundation            E     20299:FFRTQosApplyForOther:242 qos apply failed for task 5170 08-05 17:28:15.883   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.control.shell, errNum is:106! 08-05 17:28:15.884   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.root, errNum is:106! 08-05 17:28:16.279   5179-5179    C01810/SAFWK                   pid-5179              E     CheckAndGetProfilePath file path does not exist! 08-05 17:28:16.280   5179-5179    C01810/SAFWK                   pid-5179              E     DoStartSAProcess DoStartSAProcess invalid path 08-05 17:28:16.330   5180-5180    C01810/SAFWK                   pid-5180              E     CheckAndGetProfilePath file path does not exist! 08-05 17:28:16.330   5180-5180    C01810/SAFWK                   pid-5180              E     DoStartSAProcess DoStartSAProcess invalid path 08-05 17:28:16.378   5181-5181    C01810/SAFWK                   pid-5181              E     CheckAndGetProfilePath file path does not exist! 08-05 17:28:16.378   5181-5181    C01810/SAFWK                   pid-5181              E     DoStartSAProcess DoStartSAProcess invalid path 08-05 17:28:16.426   5182-5182    C01810/SAFWK                   pid-5182              E     CheckAndGetProfilePath file path does not exist! 08-05 17:28:16.426   5182-5182    C01810/SAFWK                   pid-5182              E     DoStartSAProcess DoStartSAProcess invalid path 08-05 17:28:18.399   263-298      C01719/ffrt                    samgr                 E     8683:FFRTQosApplyForOther:242 qos apply failed for task 5183 08-05 17:28:18.411   469-469      C01560/WifiHalWpaCommon        wifi_hal_service      E     WpaCliCmd, ctrl/ctrl->pSend is NULL! 08-05 17:28:18.412   469-469      C01560/WifiHalWpaCommon        wifi_hal_service      E     WpaCliCmd, ctrl/ctrl->pSend is NULL! 08-05 17:28:18.412   469-469      C01560/WifiHalStaInterface     wifi_hal_service      E     StartScan failed! ret=-1 08-05 17:28:18.413   1002-1285    C01562/ScanStateMachine        wifi_manager_se       E     WifiStaHalInterface::GetInstance().scan failed. 08-05 17:28:18.413   1002-1285    C01560/WifiScanManager         wifi_manager_se       E     DealScanFinished, state: 0! 08-05 17:28:18.421   547-5170     C01719/ffrt                    foundation            E     20338:FFRTQosApplyForOther:242 qos apply failed for task 5184 08-05 17:28:18.423   547-5170     C01719/ffrt                    foundation            E     20353:FFRTQosApplyForOther:242 qos apply failed for task 5185 08-05 17:28:18.428   547-5170     C01719/ffrt                    foundation            E     20379:FFRTQosApplyForOther:242 qos apply failed for task 5186 08-05 17:28:18.430   547-5170     C01719/ffrt                    foundation            E     20396:FFRTQosApplyForOther:242 qos apply failed for task 5187 08-05 17:28:18.747   264-944      C01719/ffrt                    hiview                E     3023:FFRTQosApplyForOther:242 qos apply failed for task 5188 08-05 17:28:21.044   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.control.shell, errNum is:106! 08-05 17:28:21.045   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.root, errNum is:106! 08-05 17:28:22.536   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.control.shell, errNum is:106! 08-05 17:28:22.537   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.root, errNum is:106! 08-05 17:28:22.633   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.control.shell, errNum is:106! 08-05 17:28:22.634   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.root, errNum is:106! 08-05 17:28:22.641   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.control.shell, errNum is:106! 08-05 17:28:22.642   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.root, errNum is:106! 08-05 17:28:26.180   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.control.shell, errNum is:106! 08-05 17:28:26.180   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.root, errNum is:106! 08-05 17:28:27.812   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.control.shell, errNum is:106! 08-05 17:28:27.812   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.root, errNum is:106! 08-05 17:28:28.838   264-944      C01719/ffrt                    hiview                E     3041:FFRTQosApplyForOther:242 qos apply failed for task 5223 08-05 17:28:31.342   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.control.shell, errNum is:106! 08-05 17:28:31.343   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.root, errNum is:106! 08-05 17:28:32.974   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.control.shell, errNum is:106! 08-05 17:28:32.975   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.root, errNum is:106! 08-05 17:28:36.502   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.control.shell, errNum is:106! 08-05 17:28:36.503   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.root, errNum is:106! 08-05 17:28:38.165   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.control.shell, errNum is:106! 08-05 17:28:38.166   632-720      C02c02/PARAM                   hdcd                  E     [param_manager.c:736]SystemReadParam failed! name is:persist.hdc.root, errNum is:106!
  • [问题求助] 鸿蒙项目从 9 升到 11,预览不可用了
    报错如下:This module is referencing one or more HSPs and cannot be previewed. To preview components in an HSP, switch to the HSP first.但新建项目,预览是可用的。
总条数:85 到第
上滑加载中