0 基础入门React Native鸿蒙跨平台开发:Interactionmanager延迟计划函数如何搞定耗时较长的工作安排 InteractionManagerInteractionmanager 可以将一些耗时较长的工作安排到所有互动或动画完成之后再进行。这样可以保证 JavaScript 动画的流畅运行。应用这样可以安排一个任务在交互和动画完成之后执行InteractionManager.runAfterInteractions((){// ...耗时较长的同步执行的任务...});和其他的延迟计划函数对比requestAnimationFrame() 用来执行在一段时间内控制视图动画的代码。setImmediate/setTimeout() 在稍后执行代码。注意这有可能会延迟当前正在进行的动画。runAfterInteractions() 在稍后执行代码不会延迟当前进行的动画。触摸处理系统会把一个或多个进行中的触摸操作认定为’交互’并且会将runAfterInteractions()的回调函数延迟执行直到所有的触摸操作都结束或取消了。InteractionManager 还允许应用注册动画在动画开始时创建一个交互“句柄”然后在结束的时候清除它。consthandleInteractionManager.createInteractionHandle();// 执行动画... (runAfterInteractions中的任务现在开始排队等候)// 在动画完成之后开始清除句柄InteractionManager.clearInteractionHandle(handle);// 在所有句柄都清除之后现在开始依序执行队列中的任务runAfterInteractions接受一个普通的回调函数或是一个PromiseTask对象该对象需要带有名为gen的方法并返回一个Promise。如果提供的参数是一个PromiseTask 那么即便它是异步的它也会阻塞任务队列直到它以及它所有的依赖任务哪怕这些依赖任务也是异步的执行完毕后才会执行下一个任务。默认情况下排队的任务会在一次setImmediate方法中依序批量执行。如果你调用了setDeadLine方法并设定了一个正整数值则任务只会在设定的时间到达后开始执行。在此之前任务会通过setTimeout来挂起并阻塞其他任务执行这样可以给诸如触摸交互一类的事件留出时间使应用可以更快地响应用户。React Native 提供了InteractionManager模块这是一个用于管理原生交互的API它可以帮助你优化应用的性能和响应性。InteractionManager主要用于确保在执行长时间运行的任务时不会阻塞原生UI线程从而避免应用出现卡顿现象。基本用法InteractionManager提供了几种方法来管理交互runAfterInteractions(task: Function): 当你想要在所有当前交互完成后执行一个任务时使用此方法。这对于在用户完成一系列交互如点击按钮后执行某些操作非常有用。createInteractionHandle(): 创建一个交互句柄你可以在执行长时间任务前调用此方法然后在任务完成后调用clearInteractionHandle(handle)来通知系统当前没有正在进行的交互。clearInteractionHandle(handle: number): 清除一个由createInteractionHandle()创建的交互句柄。示例使用runAfterInteractionsimport{InteractionManager}fromreact-native;InteractionManager.runAfterInteractions((){// 这里执行一些操作这些操作不会阻塞UI线程});使用createInteractionHandle和clearInteractionHandleimport{InteractionManager}fromreact-native;consthandleInteractionManager.createInteractionHandle();// 执行一些可能会阻塞UI线程的操作例如网络请求或大量的计算fetch(https://example.com/data).then(responseresponse.json()).then(data{// 处理数据}).finally((){InteractionManager.clearInteractionHandle(handle);});为什么使用InteractionManager在React Native中所有的UI更新都必须在JavaScript的主线程上执行。如果你在JavaScript中执行长时间运行的任务如网络请求、大量的计算等它将阻塞UI线程导致应用界面冻结或响应迟缓。使用InteractionManager可以帮助你将这类长时间运行的任务放在一个低优先级的队列中执行从而避免影响用户体验。注意事项不要在runAfterInteractions或长时间运行的任务中做UI更新。这些操作应该放在回调或Promise的.then()方法中以确保它们在UI线程上执行。性能优化虽然InteractionManager可以帮助管理长时间运行的任务但在设计应用时尽量减少需要长时间运行的任务也是很重要的。考虑使用异步操作、分批处理数据或使用Web Workers如果适用来提高性能。通过合理使用InteractionManager你可以提高React Native应用的性能和用户体验实际代码演示结果这段React Native代码实现了一个渐入动画效果的应用其核心原理基于React Hooks的自定义封装和React Native的动画系统协同工作。代码展示了如何通过自定义Hook来抽象和复用动画逻辑以及如何协调动画与用户交互之间的关系。在平台适配方面代码使用Platform.select方法根据不同的操作系统返回相应的开发菜单操作说明。对于iOS平台提示用户通过CmdR重新加载应用通过CmdD或摇动设备打开开发菜单对于Android平台则提示双击键盘R键重新加载或摇动设备、按菜单键打开开发菜单。这种设计确保了在不同设备上都能提供准确的用户指引。自定义Hook的使用是代码的核心亮点。useMount Hook通过useEffect封装了组件挂载时的逻辑执行依赖数组为空确保其只在组件初始化时运行一次。这个Hook被用于在合适的时机触发动画和回调函数。importReact,{useState,useEffect}fromreact;import{Alert,Animated,InteractionManager,Platform,StyleSheet,Text,View,}fromreact-native;constinstructionsPlatform.select({ios:Press CmdR to reload,\nCmdD or shake for dev menu,android:Double tap R on your keyboard to reload,\nShake or press menu button for dev menu,});constuseMountfuncuseEffect(()func(),[]);constuseFadeIn(duration5000){const[opacity]useState(newAnimated.Value(0));// Running the animation when the component is mounteduseMount((){// Animated.timing() create a interaction handle by default, if you want to disabled that// behaviour you can set isInteraction to false to disabled that.Animated.timing(opacity,{toValue:1,duration,}).start();});returnopacity;};constBall({onShown}){constopacityuseFadeIn();// Running a method after the animationuseMount((){constinteractionPromiseInteractionManager.runAfterInteractions(()onShown());return()interactionPromise.cancel();});returnAnimated.View style{[styles.ball,{opacity}]}/;};constApp(){return(View style{styles.container}Text{instructions}/TextBall onShown{()Alert.alert(Animation is done)}//View);};conststylesStyleSheet.create({container:{flex:1,justifyContent:center,alignItems:center},ball:{width:100,height:100,backgroundColor:salmon,borderRadius:100,},});exportdefaultApp;useFadeIn Hook负责管理渐入动画的整个生命周期。它内部创建了一个Animated.Value实例来管理透明度初始值设为0代表完全透明。通过useMount Hook在组件挂载后启动一个Animated.timing动画将透明度在指定时间内过渡到1完全不透明。这个Hook返回透明度值使得使用它的组件能够获取到动画的当前状态。Ball组件作为动画的视觉载体它使用useFadeIn Hook获取透明度值并通过useMount Hook在动画完成后执行传入的onShown回调函数。这里值得注意的是代码中使用了InteractionManager.runAfterInteractions来确保回调函数在所有动画和交互完成后才执行这种机制避免了动画过程中的卡顿和性能问题。在动画协调机制方面代码展示了如何处理动画与用户交互的优先级。InteractionManager系统默认会为每个动画创建一个交互句柄防止用户在动画过程中进行其他操作干扰动画效果。这种设计考虑到了移动应用的用户体验需求。在App组件中代码展示了如何使用Ball组件当动画完成时会触发Alert.alert显示Animation is done的提示。样式系统通过StyleSheet.create定义container样式配置了弹性布局使内容在屏幕上居中显示。ball样式定义了一个圆形元素设置宽度高度为100背景色为橙红色并通过borderRadius: 100使其呈现完美的圆形。整个应用的架构体现了React函数式组件和Hooks的现代开发模式。通过自定义Hook将动画逻辑从UI组件中分离出来实现了关注点分离和代码复用。这种设计模式不仅使代码更加清晰可维护也为实现更复杂的动画效果奠定了基础。值得注意的是代码中存在一些潜在的拼写问题如onShown和onShown的不一致使用这可能会在实际运行中导致错误。但整体上这段代码成功地展示了如何在React Native中构建声明式的动画系统以及如何通过Hook组合来创建复杂的交互体验。打包接下来通过打包命令npn run harmony将reactNative的代码打包成为bundle这样可以进行在开源鸿蒙OpenHarmony中进行使用。最后运行效果图如下显示