基于Rokid AR Studio的虚实融合应用开发实战:从环境搭建到性能优化

基于Rokid AR Studio的虚实融合应用开发实战:从环境搭建到性能优化
1. 项目缘起与核心价值又到了一年一度绞尽脑汁想拜年新花样的时候了。群发短信太老套微信红包太直接录个视频又感觉差点意思。今年马年我琢磨着能不能让祝福“活”起来从手机屏幕里跳出来实实在在地出现在亲朋好友面前正好手头有台Rokid AR眼镜一个念头就冒出来了开发一个AR虚实融合的拜年应用。想象一下你对着家人说一句“马到成功”一匹闪着金光的虚拟骏马就在现实的客厅里踏蹄嘶鸣或者比个手势一串串带着鞭炮声的立体祝福语就在空中炸开。这可比任何平面祝福都有冲击力。这个想法背后其实踩中了几个关键点。第一是情感表达的升级。拜年的核心是传递情感和祝愿AR带来的临场感和互动性能将这种情感放大数倍。第二是技术场景的落地。AR技术听起来高大上但离普通人总觉得有点远。一个节日应景的小应用恰恰是技术“接地气”、展示其亲和力的绝佳场景。第三是开发学习的实践。对于想切入AR赛道的开发者来说从一个功能明确、场景具体的“小”应用入手远比一开始就挑战复杂游戏或工业应用要容易得多能快速跑通从环境搭建、SDK调用到交互设计的全流程。Rokid AR Studio及其开放平台为这个想法提供了坚实的底座。它提供的不仅是硬件更是一套完整的空间计算解决方案——厘米级的6DoF定位、高精度的3D手势识别、基于YodaOS-Master的操作系统以及围绕OpenXR标准构建的开发者工具链。这意味着我们不需要从零开始造轮子去解决空间锚定、手势识别这些底层难题可以更专注于创意和交互逻辑本身。这次实战我就将带你一步步拆解如何利用Rokid AR Studio把一个新春AR祝福的创意变成一个可运行、可交互的真实应用。2. 开发环境与核心工具链搭建工欲善其事必先利其器。AR开发尤其是涉及空间计算和虚实融合对开发环境有特定要求。我的开发主力机是一台搭载了RTX 4060显卡的Windows 11笔记本确保有足够的图形处理能力进行实时预览和调试。2.1 核心工具选型与安装整个开发栈的核心是Unity引擎和Rokid AR SDK。Unity在XR扩展现实包含AR/VR/MR开发领域的生态成熟度是首选它的主要原因大量的插件、社区资源和学习资料能极大降低开发门槛。Unity版本选择我选择了Unity 2022.3 LTS版本。长期支持版意味着更高的稳定性对于需要与特定硬件SDK紧密集成的项目来说至关重要能避免因Unity版本迭代带来的意外兼容性问题。安装时务必勾选“Android Build Support”模块下的所有子项包括OpenJDK、Android SDK NDK Tools因为Rokid AR眼镜本质上运行的是基于Android的系统。Rokid AR SDK获取与导入前往Rokid开放平台的开发者中心下载最新版的Rokid AR SDK for Unity。通常SDK包会包含核心插件RokidARCore、示例场景Samples、必要的依赖库如ARFoundation的适配层以及详细的API文档。在Unity中我通过Assets - Import Package - Custom Package的方式导入整个.unitypackage文件。导入后检查Plugins和RokidAR相关文件夹是否已正确加入项目。关键插件检查确保项目同时安装了AR Foundation和对应平台的提供者插件如ARCore XR Plugin用于Android/ARCore设备。Rokid SDK通常会与AR Foundation进行集成通过后者来管理会话、平面检测、图像追踪等基础AR功能。在Unity的Package Manager中确认这些插件已安装并启用。注意不同版本的Rokid SDK可能对Unity和AR Foundation的版本有明确要求。务必查阅官方SDK文档的“开始使用”或“环境要求”章节进行精确匹配。我曾因使用了稍新的AR Foundation版本导致手势识别事件无法触发回退到SDK文档指定的版本后问题立刻解决。2.2 项目初始配置详解环境就绪后创建一个新的3D项目URP或Built-in渲染管线均可Rokid SDK通常都支持但需注意Shader兼容性。我选择URP因其在现代图形效果和性能上更有优势。XR插件管理打开Edit - Project Settings - XR Plug-in Management。首先在“PC Standalone”标签页下取消勾选所有插件因为我们最终目标是部署到AR眼镜在电脑上只是编辑器内预览。然后切换到“Android”标签页勾选“Rokid AR”和“ARCore”。这个顺序很重要Rokid AR插件需要作为主提供者。Player设置Android端这是将应用安装到眼镜上的关键。Other Settings中将“Package Name”改为符合反向域名格式的唯一标识例如com.yourcompany.horseyearblessing。Minimum API Level设置为Android 11API Level 30或按SDK要求设置。Target API Level设置为可用的最新版本如API Level 34。在Configuration下将“Scripting Backend”切换为IL2CPP以提升执行效率和安全性。同样在Configuration下勾选“ARM64”架构这是现代高性能Android设备的标配。场景基础设置删除默认的Main Camera从Rokid SDK的示例Prefab中找到一个通常名为RokidARController或RokidAR Session Origin的预制体拖入场景。这个预制体集成了AR相机、手势识别器、射线交互器等核心组件。它就是我们用户在AR世界中的“眼睛”和“双手”。完成以上步骤基础框架就搭建好了。你可以尝试构建一个空APK安装到眼镜上通过USB连接在Unity中Build And Run如果能看到通过眼镜摄像头捕捉的现实世界画面并且没有崩溃那么恭喜你最难的环境配置关已经过了。3. 虚实融合场景设计与关键技术点拆解一个AR拜年应用核心在于“虚”与“实”的自然融合。我们的“虚”是各种春节元素福字、鞭炮、金马、祝福语的3D模型和特效“实”则是用户所处的真实物理环境。让“虚”稳定、合理地出现在“实”中并与之互动是技术关键。3.1 空间锚定与平面检测虚拟物体不能飘在空中它需要“粘”在真实世界的某个表面上。Rokid SDK通过集成AR Foundation提供了强大的空间理解能力。平面检测Plane Detection这是最常用的锚定方式。SDK会实时分析摄像头画面识别出水平面如地板、桌面和垂直面如墙壁。在代码中我们可以监听平面添加、更新的事件。当检测到一个足够大的平面时我选择让一个半透明的网格预览出现在该平面上提示用户此处可以放置物体。// 示例在AR平面管理器的事件中处理 private void OnPlaneAdded(ARPlane plane) { if (plane.alignment PlaneAlignment.HorizontalDown || plane.alignment PlaneAlignment.HorizontalUp) { // 创建或激活一个视觉指示器如半透明Quad在plane.transform位置 ShowPlacementIndicator(plane.transform.position, plane.transform.rotation); } }手势放置当用户通过凝视射线或手势如食指点击确认位置后我们就在该坐标点实例化祝福物体。这里的关键是坐标转换。手势识别模块会返回一个在AR世界空间中的Pose包含位置和旋转我们需要将这个Pose作为虚拟物体的初始Transform。实操心得平面检测在纹理丰富、光照充足的环境下效果最好。在纯白桌面或昏暗环境下检测可能会失败或延迟。因此在应用引导提示中可以建议用户“找一个纹理清晰的桌面或地面”。另外对于像“空中绽放的烟花”这类不需要附着平面的物体我们可以直接将其锚定在用户前方一定距离例如2米的空间点上使用RokidARCamera的主相机Transform向前偏移来计算生成位置。3.2 3D手势交互实现Rokid AR的一大亮点是其高精度的3D手势识别无需手柄徒手即可操作。这对于拜年应用来说交互自然度直接拉满。手势事件订阅Rokid SDK通常提供一个手势管理器如RokidHandGestureManager。我们需要在代码中订阅其手势识别事件。public RokidHandGestureManager gestureManager; void Start() { if (gestureManager ! null) { gestureManager.OnGestureDetected HandleGestureDetected; } } void HandleGestureDetected(RokidHandGesture gesture) { switch (gesture.type) { case HandGestureType.Pinch: // 捏合手势常用于选中/确认 if (IsPointingAtObject()) { ActivateBlessingObject(); } break; case HandGestureType.ThumbsUp: // 点赞手势 SpawnFireworks(); // 触发放烟花效果 break; case HandGestureType.OpenHand: // 张开手掌 ShowBlessingMenu(); // 显示祝福语选择菜单 break; } }交互反馈设计纯手势交互缺乏物理触感因此视觉和听觉反馈至关重要。当用户的手势射线悬停在一个可交互的虚拟物体如一个旋转的“福”字上时物体应该高亮、轻微放大或发出微光。当触发“捏合”选中时可以配合一个短促的音效和粒子特效如星光闪烁明确告知用户操作成功。手势交互的避坑指南识别范围手势识别有最佳工作距离通常是距离摄像头0.5米到2米。在UI引导中需要提醒用户。环境光过于昏暗或强光直射手部会严重影响识别率。手势保持像“捏合”这样的手势是检测到“捏合”动作的瞬间触发一次事件还是需要保持捏合状态这需要在设计交互逻辑时想清楚。对于放置操作我采用了“捏合-保持-拖动-释放”的流程更符合直觉。3.3 春节特效与3D资源整合视觉表现是AR拜年应用吸引人的直接因素。我准备了以下几类资源3D模型一匹昂首奔腾的骏马马年主题、元宝、灯笼、春联卷轴等。这些模型需要在3D建模软件如Blender中提前优化面数不宜过高建议单个模型在5万面以内合理拆分UV并烘焙光影贴图Lightmap以在移动端获得最佳性能与效果平衡。粒子特效用于鞭炮爆炸、烟花绽放、金光闪烁、文字浮现等效果。Unity的VFX Graph或Shuriken粒子系统都能制作。要点是控制同时存在的粒子数量使用GPU Instancing进行合批渲染并设置合理的生命周期避免特效结束后仍占用资源。祝福语呈现单纯的3D文字可能不够生动。我的方案是3D文字动画使用Unity的TextMeshPro创建3D文本然后通过DoTween或编写脚本为其添加“逐个字符弹出”、“波浪式起伏”、“环绕旋转”等动画。图文结合将祝福语如“龙马精神”设计成一个徽章或卷轴样式文字作为纹理的一部分贴在模型上让模型如一个展开的卷轴执行出现动画。空间音频当祝福语出现时伴随一声喜庆的铃铛或古筝音效。Rokid眼镜支持空间音频可以设置声音源Audio Source的spatialBlend属性为1让声音听起来像是从虚拟物体位置发出的沉浸感更强。将所有资源导入Unity后需要为它们配置合适的材质和Shader。对于AR应用推荐使用URP Lit或Unlit Shader并谨慎使用复杂的实时光影因为移动端性能和真实世界光照条件多变固定光照可能显得突兀。更佳实践是使用“光照探针”Light Probe来让虚拟物体采样周围环境的光照信息使其色调更好地融入真实场景。4. 核心功能模块开发实战有了资源和基础框架接下来就是像搭积木一样把各个功能模块实现并串联起来。我的应用主要设计了三个核心场景主菜单、祝福放置与交互、合影分享。4.1 主菜单与场景管理AR应用的主菜单不能是传统的2D UI面板而应该是一个悬浮在空间中的3D界面。我设计了一个圆环状的菜单选项如“放置福字”、“召唤金马”、“录制祝福”像行星一样环绕在中心。3D UI交互每个菜单选项都是一个独立的3D物体带有碰撞体Box Collider。通过Rokid SDK提供的RokidRaycaster射线投射器将用户手势的指向从眼镜发射的一道射线与这些碰撞体进行检测。当射线击中某个选项时高亮该选项当检测到“捏合”手势时触发该选项对应的功能。public class SpatialButton : MonoBehaviour { public void OnRaycastHit() // 被射线击中时调用 { GetComponentRenderer().material.color Color.yellow; // 高亮 } public void OnRaycastExit() { GetComponentRenderer().material.color Color.white; // 恢复 } public void OnSelect() // 被选中捏合时调用 { // 触发对应的功能例如加载祝福物体预制体 blessingManager.SpawnBlessingObject(this.objectType); } }场景状态机使用一个简单的状态模式State Pattern来管理应用的不同模式如MenuMode、PlacementMode、RecordingMode。这样能清晰地隔离不同模式下的输入处理和逻辑避免代码混乱。4.2 祝福物体的动态生成与交互逻辑这是应用最核心的模块。当用户从菜单选择“金马送福”后应用进入放置模式。预览与放置如前所述调用平面检测并生成一个半透明的金马预览模型跟随用户的视线焦点射线与检测到的平面的交点移动。当用户做出“捏合”手势时记录下当前预览模型的位置和旋转销毁预览模型并在同一位置实例化出真正的、带完整材质和动画的金马模型。物体交互放置后的物体不应是静态的。我为金马模型添加了点击射线选中后捏合交互点击后金马会仰头长嘶一声播放动画和音效然后从口中“吐”出一串3D文字“马到成功”文字会缓缓上升并旋转。这个逻辑通过给金马物体挂载一个交互脚本来实现。public class BlessingHorse : MonoBehaviour, IRokidSelectable { public GameObject blessingTextPrefab; public Animator horseAnimator; public AudioClip neighSound; public void OnSelected() { // 1. 播放嘶鸣动画 horseAnimator.SetTrigger(Neigh); // 2. 播放音效 AudioSource.PlayClipAtPoint(neighSound, transform.position); // 3. 在嘴部位置生成祝福文字 GameObject textObj Instantiate(blessingTextPrefab, mouthPosition.transform.position, Quaternion.identity); // 4. 为文字添加上升动画 textObj.GetComponentBlessingText().FloatUp(); } }多物体管理与性能用户可能会放置多个祝福物体。需要用一个列表来管理所有已放置的物体实例。当物体数量过多例如超过10个或用户远离某个物体一定距离后可以考虑将其替换为LODLevel of Detail低模版本或直接隐藏以维持流畅的帧率。4.3 虚实融合合影与分享功能拜年的快乐在于分享。我设计了一个“AR合影”功能允许用户将自己与放置好的AR祝福场景同框录制一段短视频。录屏实现Unity提供了ScreenCapture类但在AR场景中我们需要录制的是“透视视频”——即包含真实背景和虚拟物体的合成画面。Rokid SDK通常提供了专门的录屏API或组件。其原理是在每一帧渲染完成后从渲染纹理Render Texture中读取最终的合成图像编码为视频帧。核心步骤是初始化视频编码器如使用MediaRecorder或第三方插件。在Update或一个专门的后期渲染回调中获取当前相机的渲染目标纹理。将纹理数据提交给编码器。开始/停止录制由用户手势如双手比框控制。分享集成录制生成的MP4文件保存在眼镜的本地存储中。通过调用Android系统的原生分享意图Intent可以将视频文件分享到微信、QQ等社交平台。这里需要编写Android原生插件Android Java Plugin或在Unity中使用UnityEngine.Android类来调用系统API。// 简化示例调用Android分享 public void ShareVideo(string videoPath) { AndroidJavaClass intentClass new AndroidJavaClass(android.content.Intent); AndroidJavaObject intentObject new AndroidJavaObject(android.content.Intent); intentObject.CallAndroidJavaObject(setAction, intentClass.GetStaticstring(ACTION_SEND)); intentObject.CallAndroidJavaObject(setType, video/mp4); AndroidJavaClass uriClass new AndroidJavaClass(android.net.Uri); AndroidJavaObject fileObject new AndroidJavaObject(java.io.File, videoPath); AndroidJavaObject uriObject uriClass.CallStaticAndroidJavaObject(fromFile, fileObject); intentObject.CallAndroidJavaObject(putExtra, intentClass.GetStaticstring(EXTRA_STREAM), uriObject); AndroidJavaClass unityPlayer new AndroidJavaClass(com.unity3d.player.UnityPlayer); AndroidJavaObject currentActivity unityPlayer.GetStaticAndroidJavaObject(currentActivity); currentActivity.Call(startActivity, intentObject); }重要提示视频录制和编码是CPU和GPU密集型操作会显著增加功耗和发热。务必在录制时降低图形设置如关闭抗锯齿、降低阴影质量并设置合理的视频分辨率如720p和帧率30fps。同时提供清晰的录制状态提示如一个红色的录制图标并限制单次录制时长如最长15秒。5. 性能优化与调试技巧实录AR应用运行在电池供电的移动设备上且需要实时处理摄像头画面、SLAM、手势识别和3D渲染性能压力巨大。优化不到位轻则发热卡顿重则直接闪退。5.1 渲染性能优化Draw Call与合批使用Unity的Frame Debugger工具分析每一帧的Draw Call数量。目标是尽可能减少。对于大量重复的静态物体如多个相同的鞭炮粒子使用静态合批Static Batching。对于动态但材质相同的物体如多个祝福文字确保它们使用相同的材质球以触发动态合批Dynamic Batching或使用GPU Instancing。模型与纹理优化模型在保证视觉精度的前提下使用尽可能低的多边形模型。使用LOD Group组件为复杂模型如金马设置多个细节层级距离远时自动切换到低模。纹理所有纹理尺寸应为2的幂次方如512x512并使用合适的压缩格式Android用ASTC。避免使用超大纹理超过2048x2048。将多个小纹理合并到一张图集Atlas中可以减少材质切换带来的Draw Call。光照与阴影实时阴影在移动AR中是性能杀手。我的做法是完全禁用实时阴影。对于需要阴影效果的地方使用“假阴影”——即一个简单的、透明度渐变的圆形面片Decal放在物体下方。环境光照使用光照探针烘焙避免每帧计算。后期处理谨慎使用屏幕空间环境光遮蔽SSAO、 Bloom等全屏后处理效果。如果必须使用选择性能开销最小的方案并考虑只在录制合影时启用平时预览时关闭。5.2 脚本与逻辑优化Update中的操作Update()方法每帧调用里面的代码必须高效。避免在Update中进行复杂的计算、查找游戏对象Find、GetComponent或分配堆内存如频繁new对象、字符串拼接。将这些操作缓存起来或移到Start、事件触发时执行。对象池Object Pooling对于频繁创建和销毁的对象如粒子特效、弹出的祝福文字使用对象池是必须的。预先实例化一定数量的对象并禁用需要时从池中取出启用用完放回池中禁用避免反复实例化Instantiate和垃圾回收GC带来的卡顿。public class BlessingTextPool : MonoBehaviour { public GameObject textPrefab; public int poolSize 10; private QueueGameObject pool new QueueGameObject(); void Start() { for (int i 0; i poolSize; i) { GameObject obj Instantiate(textPrefab); obj.SetActive(false); pool.Enqueue(obj); } } public GameObject GetText() { if (pool.Count 0) { GameObject obj pool.Dequeue(); obj.SetActive(true); return obj; } return Instantiate(textPrefab); // 池空时 fallback } public void ReturnText(GameObject obj) { obj.SetActive(false); pool.Enqueue(obj); } }AR会话管理当应用进入后台或用户长时间不操作时可以考虑暂停AR会话ARSession暂停平面检测和摄像头图像处理以节省电量。当应用回到前台时再恢复。5.3 真机调试与问题排查在Unity编辑器中运行良好不代表在眼镜上也没问题。真机调试是最后一关也是最关键的一关。使用Android Logcat通过USB连接眼镜在Unity编辑器中选择Build And Run后打开Window - Analysis - Android Logcat窗口。这是排查崩溃、错误和警告信息的最直接工具。重点关注Fatal、Error级别的日志。性能分析器在眼镜上运行应用然后在Unity编辑器中通过Window - Analysis - Profiler连接设备。观察CPU、GPU、内存、渲染等模块的占用情况。定位到具体是哪一帧、哪个函数调用导致了性能峰值。常见问题速查表问题现象可能原因排查与解决思路应用安装后打开立即黑屏/闪退1. AndroidManifest权限缺失2. SDK库文件.so架构不匹配3. Unity版本或插件版本不兼容1. 检查是否声明了相机、存储等必要权限。2. 确认APK构建时只勾选了ARM64架构。3. 核对Rokid SDK文档使用其指定的Unity和AR Foundation版本。能看到真实世界但无法检测平面1. 环境光线太暗或纹理单一2. AR会话配置未启用平面检测3. 摄像头对焦问题1. 提示用户改善环境。2. 检查ARPlaneManager组件是否启用detectionMode是否正确设置。3. 尝试在代码中请求自动对焦。手势识别不灵敏或完全无效1. 手势识别服务未初始化或未启动2. 手部不在摄像头视野或距离不合适3. 手势事件未正确订阅1. 确认RokidHandGestureManager已添加到场景并已调用初始化方法。2. 在UI上添加手势检测区域的视觉提示。3. 调试检查OnGestureDetected事件是否被触发。虚拟物体抖动或漂移1. SLAM跟踪丢失快速移动或特征点少2. 虚拟物体锚定不稳定1. 优化环境保持相对静止后再放置物体。2. 考虑使用Rokid SDK可能提供的更稳定的锚点组件或对物体位置进行平滑滤波如Kalman Filter。录制视频卡顿或失败1. 编码器性能不足2. 分辨率/码率设置过高3. 存储空间不足或权限问题1. 录制时临时降低渲染质量。2. 将视频参数调整为720p 30fps中等码率。3. 检查并申请WRITE_EXTERNAL_STORAGE权限。踩坑实录我在开发中遇到最棘手的问题是在特定角度快速转头时所有虚拟物体会发生剧烈跳变。通过Profiler发现在跳变帧ARCore相关的线程CPU占用率飙升。最终排查发现是因为我在同一场景中同时启用了ARPlaneManager和ARImageTracker用于图像识别两者在某些情况下产生了资源冲突。解决方案是在不需要图像追踪时禁用ARImageTracker组件或者将平面检测和图像检测分时段进行。这个教训告诉我AR Foundation的各个子系统需要仔细管理其生命周期。6. 项目构建、部署与迭代思考经过一系列开发、调试和优化应用终于达到了可发布的状态。最后一步是构建APK并安装到Rokid眼镜上进行最终测试。6.1 构建与签名在Unity的Build Settings中确保场景列表正确平台切换为Android。点击Player Settings进行最终检查Other Settings-Identification包名、版本号。Other Settings-Configuration脚本后端IL2CPP目标架构ARM64。Publishing Settings这是生成可发布APK的关键。你需要一个Keystore来为应用签名。如果还没有可以创建一个新的Create New Keystore并妥善保管密码和别名信息。这是应用的身份标识未来更新必须使用相同的Keystore。点击Build选择一个输出目录Unity会开始编译。第一次构建可能会花费较长时间因为它需要转换所有资源并编译IL2CPP代码。构建成功后你会得到一个.apk文件。6.2 部署与最终测试通过USB数据线将Rokid AR眼镜连接到电脑。确保眼镜已开启开发者模式和USB调试通常在设置-关于设备中多次点击版本号开启开发者选项。在命令行中使用adb install -r your_app.apk命令安装或者更简单的方式是在Unity构建时直接选择Build And RunUnity会自动完成安装和启动。安装后在眼镜的应用列表中找到你的应用图标启动它。进行全方位的最终测试功能测试逐一测试所有菜单选项、手势交互、物体放置、动画播放、音效、录屏分享等功能是否正常。兼容性测试在不同光照环境明亮室内、昏暗房间、不同表面木桌、地毯、白墙下测试平面检测和跟踪稳定性。性能与发热测试连续使用应用15-20分钟观察帧率是否稳定眼镜发热是否在可接受范围内。用户体验测试让没有接触过这个应用的朋友试用观察他们是否能无师自通地完成核心操作记录下他们困惑或卡住的地方。6.3 未来迭代方向这个马年AR拜年应用是一个很好的起点但AR的想象力远不止于此。基于这次开发经验我认为后续可以从以下几个方向深化多用户互动利用网络如Wi-Fi P2P或云端服务实现多人共享同一个AR空间。比如家人可以各自戴上眼镜看到彼此放置的祝福物体甚至一起“舞龙”实现真正的AR远程团圆拜年。更智能的交互结合Rokid的语音交互能力实现“语音手势”的多模态输入。用户可以直接说“来一匹马”或者“把那个福字放大”交互会更自然。物理效果增强集成轻量级的物理引擎让虚拟物体能与真实世界发生更拟真的互动。比如鞭炮爆炸后虚拟的彩纸屑可以飘落并堆积在真实的桌面上。个性化内容生成结合AIGC技术让用户输入一句祝福语自动生成一个独特的、带简单动画的3D文字或图案让每次祝福都独一无二。开发这个应用的过程让我深刻体会到AR技术正在从炫技走向实用。它不再是一个遥远的科幻概念而是可以通过我们开发者的双手创造出温暖、有趣、连接人与人情感的真实工具。从环境搭建时的手忙脚乱到调试手势识别时的反复尝试再到最终看到家人对着空中跃出的金马惊喜大笑的那一刻所有的代码和调试都值了。希望这篇实战记录能为你打开一扇AR开发的大门期待看到更多有趣、有温度的AR应用诞生。