鸿蒙Flutter实战:15-Flutter引擎Impeller鸿蒙化、性能优化与未来
Flutter 技术原理
Flutter 是一个主流的跨平台应用开发框架,基于 Dart 语言开发 UI 界面,它将描述界面的 Dart 代码直接编译成机器码,并使用渲染引擎调用 GPU/CPU 渲染。
渲染引擎的优势
使用自己的渲染引擎,这也是 Flutter 与其他跨平台框架最大的区别。
与 React Native 等高度依赖原生组件的框架不同,Flutter 摆脱了原生组件依赖,界面布局更加灵活,多端展示效果高度一致。由于渲染引擎自建,性能优化空间更大,这也是为什么Flutter 以流畅著称。
Impeller 渲染引擎由来
Flutter 的渲染引擎经历了多次迭代,早期全端使用 Skia, 后来为了解决 iOS 上着色器编译卡顿问题,Flutter 团队开发了新一代渲染引擎 Impeller。由于表现优异,Impeller 已经成为 Flutter 未来的发展方向。
渲染引擎将着色器编译成GPU指令,也就是二进制代码。
着色器是一种图形绘程序,它定义了如何绘制一个图形,比如颜色、形状、变换等。
Flutter在解决卡顿问题上,基于Skia做了多次努力和尝试,始终不尽人意,最终才有了Impeller。
Impeller 的设计目标包括: 消除首次卡顿、降低帧渲染驱动开销、利用现代 GPU 并行渲染能力
Impeller 与 Vulkan
Vulkan 是 OpenGL 推出的下一代图形 API,在安卓上,Flutter Impeller 调用 Vulkan 实现界面渲染。
- Impeller 实现了常用的着色器,支持参数化,通过预编译色器来避免编译卡顿问题
- 分层架构简化了渲染过程,每一层基于下层能力执行特定功能,高效且易用于维护更新
- 绘制命令容易聚合,易于拆分和并行
- 渲染设计与图形API解耦
Impeller 鸿蒙化
Impeller 的鸿蒙化基于 Vulkan, 通过 ArkUI 提供的 XComponent 组件承载 Flutter 视图。
与其他平台一样,通过 Method Channel , Dart 调用 ArkTS 来实现原生能力的调用。
XComponent 如何承载 Flutter 视图
通过 XComponet 获取到系统底层的 OHNativeWindow 实例, 这个就是鸿蒙的原生窗口,通过鸿蒙提供的扩展 VK_OHOS_surface, 将这个窗口转成一个 Vulkan 中的 VKSurface, 进而通过 VKSwapchain 实现了窗口绘制。
外接纹理:系统产生的图形图像如何嵌入 Flutter 显示
借助 XComponent,Flutter 绘制的界面可以显示在鸿蒙中。那么如果是非 Flutter 绘制的界面,如系统相机、视频等,如何嵌入到 Flutter 界面中呢?这就涉及到外接纹理了。
以相机为例,如果在 Flutter 中使用相机,当然最基础的可以通过 Method Channel 通信,将数据传递过来,但这个过程显然非常耗时,性能堪忧。另外一种方案是通过挖孔,叠加系统页面和 Flutter 画面,但这可能带来两套界面的操作、动画不一致问题。鸿蒙化采用了难度更高的数据导入方案,即将外部数据导入到 Flutter,将这些数据以纹理组件形式绘制。
鸿蒙化外接纹理涉及编码数据传输,如何解决性能问题
NativeBuffer 由鸿蒙提供, 通过它可以实现内存共享。那么外部导入的数据,通过 NativeBuffer,可以直接让 GPU 使用,避免了因数据拷贝造成的性能损失。
无论是 VKImage, 还是 GLTexture,都可以使用 NativeBuffer。
如何解决花屏问题
与安卓不同,Impeller 鸿蒙化方案采用了 GPU 硬件级的同步机制,保护数据读取,防止数据竞争,避免图像的花屏,通过 CPU 解耦,减少了空转时间,提高了性能。
Flutter 引擎侧不需要等待 Buffer 读写完成再调用绘制能力,只要保证 GPU 在绘制队列时,涉及 Buffer 数据的信号量状态为已读取即可,减少了 CPU 空等时间造成的性能损失。
渲染管线预加载
Impeller 通过预编译着色器避免了 Skia 中的运行时编译,但启动时需要加载这些着色器(也就是加载渲染管线),这就会出现明显的白屏时间。要解决这一问题,那就需要预加载渲染管线。
鸿蒙 Flutter 在运行时,首先创建 Dart 虚拟机解析 UI,在这个过程中同步进行渲染管线加载,从而实现首帧快速上屏,时延降低 50ms。
这部分不需要开发者操作,SDK 会自动完成。
混合开发加载优化:页面预加载
从原生 ArkUI 页面跳转到 Fluter 页面,需要先初始化 Flutter 引擎(这个过程耗时较长),再渲染首帧页面,这就会出现明显卡顿。
开发者可以提前手动调用 Flutter 引擎初始化 API,来解决这一卡顿问题。例如用户在触摸发生时,同步初始化 Flutter 引擎,等到用户抬手以后,就可以立即跳转到 Flutter 页面,整个过程会更加流程。
性能测试
通过预加载,可以节省一半的跳转时间。与 Skia 方案相比,Impeller 的转场流畅度提升显著。
与 Skia 方案相比,Impeller 方案在性能上表现更好。
鸿蒙 Flutter 的未来
鸿蒙 Flutter 适配团华为主导,计划每年推出 1-2 个比较大的版本,这两个大版本通过 fork 官方当时的主要版本来实现。至于能否将鸿蒙适配的部分合并到 Flutter 官方,还要看 Google 的态度。
结合前段时间 Flutter 社区版本 Flock 的推出,笔者持乐观态度。虽然 Google 在 Flutter 更新这方面进度缓慢,但社区版本带来不少想象力。多个 SDK 版本并存并不意味着分裂,竞争带来更多的活力。这点可以参考 Java,除了甲骨文主导的 OracleJDK, 还有 OpenJDK, AdoptOpenJDK 等十几种社区版本。
除了已有的插件开发方式,鸿蒙 Flutter 计划推出一种成本更低的方案,即通过一种统一接口描述,自动生成各端调用代码,省去开发者的编码工作。
总结
Flutter 作为一种流行的跨平台框架,支持鸿蒙是大势所趋。华为躬身入局,为 Flutter 社区带来了强劲动力。
从目前各方反馈来看,Flutter 应该是仅次于 ArkTs 的最佳适配方案。 不论是官方、还是开源社区、亦或是广大的开发者,都对 Flutter 有着强烈的诉求。 HarmonyOS 希望更多应用尽快适配鸿蒙,开发者或者是厂商,也希望以更低的成本最快上架;ArkTS 仍然有不少需要改进之处,就拿热重载一项与之对比,Flutter 不论从易用性、稳定性和成熟度已经遥遥领先。
对于平台独有的特性,如鸿蒙中的各种 Picker 组件、免权限按钮等,这与在其他平台上一样,是属于原生语言独有的优势所在。
虽然 Flutter 鸿蒙化已经初见成效,不少三方 Flutter 应用也快速适配上架,但生态建设仍需诸多时间,三方库还需要共建共享。
鸿蒙未来可期,Flutter 的鸿蒙化,为这个沉寂许久的框架,带来了新鲜血液。
参考资料
- Flutter lmpeller鸿蒙化实践 (第一期)
- Flutter 新一代图形渲染器 Impeller
- Understanding Impeller: A Deep Dive into Flutter’s Rendering Engine
- Flock
相关文章:
鸿蒙Flutter实战:15-Flutter引擎Impeller鸿蒙化、性能优化与未来
Flutter 技术原理 Flutter 是一个主流的跨平台应用开发框架,基于 Dart 语言开发 UI 界面,它将描述界面的 Dart 代码直接编译成机器码,并使用渲染引擎调用 GPU/CPU 渲染。 渲染引擎的优势 使用自己的渲染引擎,这也是 Flutter 与其…...
华为交换机---自动备份配置到指定ftp/sftp服务器
华为交换机—自动备份配置到指定ftp服务器 需求 交换机配置修改后及时备份相关配置,每次配置变化后需要在1分钟后自动进行保存,并且将配置上传至FTP服务器;每隔30分钟,交换机自动把配置上传到FTP服务器。 1、定时保存新配置的时间间隔为*分钟(1天=1440),默认为30分钟(…...
dns网址和ip是一一对应的吗?
DNS网址和IP地址是一一对应的吗?我们在上网时,为什么总是使用网址而不是一串数字?这些问题其实涉及到互联网的基本运作原理。DNS(域名系统)是我们日常上网过程中一个不可或缺的部分,它帮助我们将人类易于记…...
Couchbase 和数据湖技术的区别、联系和相关性分析
Couchbase 和数据湖技术(如 Delta Lake、Apache Hudi、Apache Iceberg)分别是两类不同的数据存储与管理系统,但它们也可以在特定场景中结合使用,以下是它们的区别、联系和相关性分析: 区别: 1. 核心用途&a…...
微信小程序提示 miniprogram-recycle-view 引入失败
npm i --save miniprogram-recycle-view 安装需要使用的页面的json文件中配置 {"usingComponents": {"recycle-view": "miniprogram-recycle-view/recycle-view","recycle-item": "miniprogram-recycle-view/recycle-item"…...
RAG_Techniques合集
Github 專案RAG_Techniques 列出了所有想得到的RAG最佳實踐和技巧!以下是完整的目錄,內容豐富到不行!💡 Simple RAG 🌱Context Enrichment Techniques 📝Multi-faceted Filtering 🔍Fusion Ret…...
泊松融合 实例2025
目录 例子1: 实现代码: 原作者代码: 本博客直接给出来最好的效果和源代码 参数说明: 效果不好,不推荐的参数:MONOCHROME_TRANSFER,NORMAL_CLONE 例子1: 目标图: 原图: 效果图: 实现代码: 坐标是要目标图上中心点坐标: import cv2if __na...
反直觉导致卡关-迫击炮谜题
这个谜题,在两周目中先后卡了我至少三个小时,先后缓慢装填并发射迫击炮弹尝试了数百次。 一周目卡了很久,稀里糊涂的过了,想不到二周目还会卡那么久。 研究了很多播主的攻略,但还是一头雾水, 直到分析其…...
Vue2
前几篇和大家分享了Vue2基础篇,现在和大家分享一下Vue2的进阶篇 普通组件的注册: 局部组件:只能在注册的组件内使用 1.创建vue文件 三部分组成 2在使用的组件内部导入并且注册 全局组件:所有组件内部都可以用 组件的三大组成部分 结构&…...
PDF文件提示-文档无法打印-的解决办法
背景信息 下载了几个签名的PDF文件,想要打印纸质版,结果打印时 Adobe Acrobat Reader 提示【文档无法打印】: 解决办法 网上的方案是使用老版本的PDF阅读器, 因为无法打印只是一个标识而已。 PDF文件不能打印的五种解决方案-zhihu 这些方…...
C语言进阶(3)--字符函数和字符串函数
本章重点 重点介绍处理字符和字符串的库函数的使用和注意事项 目录 0.前言 1.函数介绍 1.1 strlen - 计算字符串长度 1.2 strcpy - 复制字符串 1.3 strcat - 追加字符串 1.4 strcmp - 字符串比较 1.5 strncpy - 受限制复制 1.6 strncat - 受限制追加 1.7 strncmp - 受限制比…...
英文词汇解析:“Arguably“ 的用法与含义
中文版 英文词汇解析:“Arguably” 的用法与含义 在英语中,“arguably” 是一个常用的副词,用来表达某种观点可能是正确的,尽管它可能存在争议或需要进一步讨论。它通常用于陈述观点或看法时,给出一种有依据但又留有…...
Win 11 拷贝文件失败,错误0x800704C8: 请求的操作无法在使用用户映射区域打开的文件上执行。
手机拷贝照片到电脑,再把电脑的照片拷贝到移动硬盘的过程报错。 一个意外错误使你无法移动该文件。如果你继续收到此错误,可以使用错误代码来搜索有关此问题的帮助。 错误 0x800704C8: 请求的操作无法在使用用户映射区域打开的文件上执行。 解释…...
SpringBoot原理分析-1
SpringBoot原理分析 作为一个javaer,和boot打交道是很常见的吧。熟悉boot的人都会知道,启动一个springboot应用,就是用鼠标点一下启动main方法,然后等着就行了。我们来看看这个main里面。 SpringBootApplication public class E…...
我用Ai学Android Jetpack Compose之Button
答案来自 通义千问,代码同样需要到Android Studio里实践,才能学会。 我要学Button,麻烦介绍一下 当然可以!Button 是 Jetpack Compose 中用于创建可点击按钮的 Composable 函数。它提供了丰富的配置选项来定制按钮的外观和行为。…...
《量子比特:解锁人工智能并行计算加速的密钥》
在科技飞速发展的今天,量子计算与人工智能的融合正成为一股强大的力量,为诸多领域带来变革性的突破。量子比特作为量子计算的核心要素,其独特的叠加和纠缠特性为人工智能算法实现并行计算加速提供了前所未有的机遇。 量子比特的叠加特性&…...
【SpringBoot】当 @PathVariable 遇到 /,如何处理
1. 问题复现 在解析一个 URL 时,我们经常会使用 PathVariable 这个注解。例如我们会经常见到如下风格的代码: RestController Slf4j public class HelloWorldController {RequestMapping(path "/hi1/{name}", method RequestMethod.GET)publ…...
用QT实现 端口扫描工具1
安装在线QT,尽量是完整地自己进行安装,不然会少包 参考【保姆级图文教程】QT下载、安装、入门、配置VS Qt环境-CSDN博客 临时存储空间不够。 Windows系统通常会使用C盘来存储临时文件。 修改临时文件存储位置 打开系统属性: 右键点击“此电…...
基于单片机的肺功能MVV简单测算
肺功能MVV一般是指肺部每分钟的最大通气量。 MVV本身是最大值的英文缩写,在临床上,肺功能MVV表示肺部每分钟最大通气量,用以衡量气道的通畅度,以及肺部和胸廓的弹性、呼吸肌的力量。 肺部每分钟的最大通气量的参考值男性与女性之…...
入手STM32单片机学习指南
目录 引言 一、基础概念 1.1 STM32单片机简介 1.2 ARM Cortex-M系列处理器 1.3 微控制器的基本组成 二、开发环境搭建 2.1 选择开发板 2.2 安装开发软件 2.3 配置开发环境 三、编程入门 3.1 GPIO编程 3.2 UART编程 3.3 ADC编程 引言 STM32单片机是基于ARM Cortex…...
无法定位软件包cuda
无法定位软件包cuda 如果你在使用 sudo apt install cuda 命令安装 CUDA 时遇到“无法定位软件包cuda”的问题,这可能是由于你的系统没有正确配置 CUDA 的安装源。以下是一些可能的解决方案: 更新 Ubuntu 软件源并升级到最新版本的软件包。你可以选择使…...
GWAS数据和软件下载
这部分主要是数据获取,以及软件配置方法。 一、配套数据和代码 数据和代码目前在不断的更新,最新的教程可以私信,我通过后手动发送最新版的pdf和数据代码。发送的压缩包,有电子版的pdf和数据下载链接,里面是最新的百度网盘的地址,下载到本地即可。然后根据pdf教程,结合配套的…...
SpringBoot3-深入理解自动配置类的原理(尚硅谷SpringBoot3-雷神)
文章目录 目录了解自动配置 一、导入对应场景的Mean依赖:1、引入依赖**找到自动配置类的所有配置都存放在哪里** 二、编写主程序:SpringBootApplication观察源码时所需要知道的几个核心注解:1、观察SpringBootApplication源码都做了什么 三、…...
MOE怎样划分不同专家
MOE怎样划分不同专家 目录 MOE怎样划分不同专家MOE划分不同专家的方法LLM模型拆分的方法**子模块拆分法**:**多头拆分法**:**层间拆分法****基于功能的拆分法**Python代码实现MOE划分不同专家以及LLM模型拆分的方法及举例如下: MOE划分不同专家的方法 ffn前馈神经网络 独立…...
NLP CH3复习
CH3 3.1 几种损失函数 3.2 激活函数性质 3.3 哪几种激活函数会发生梯度消失 3.4 为什么会梯度消失 3.5 如何解决梯度消失和过拟合 3.6 梯度下降的区别 3.6.1 梯度下降(GD) 全批量:在每次迭代中使用全部数据来计算损失函数的梯度。计算成本…...
Pyecharts SVG 标记使用笔记
Pyecharts SVG 标记使用笔记 在数据可视化中,图表的标记点常常用于突出显示重要数据点。Pyecharts 提供了丰富的标记点配置选项,其中使用 SVG 路径来自定义标记点的样式是一个非常强大的功能。本文将详细介绍如何在 Pyecharts 中使用 SVG 路径来定制标记…...
C++ 文件操作
文件操作 // 文件操作 // 程序运行时产生的数据都属于临时数据,程序结束后临时数据会被操作系统释放 // 通过文件操作可以将数据持久化 // c 中文件操作需要包含头文件 <fstream>// 文件类型分为两种: // 文本文件: 文件以文本的ASCII…...
享元模式详解
享元模式详解 一、定义 享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享对象来尽量减少内存的使用。它通过将重复使用的对象分离成共享和非共享部分,达到复用的目的,从而有效节省内存。具体来说&#x…...
数据库中的并发控制
并发操作带来的数据不一致性 1、并发控制:为了保证事务的隔离性和一致性,数据库管理系统需要对并发操作进行正确调度 并发控制的主要技术有:封锁、时间戳、乐观控制法、多版本并发控制等 并发操作带来的数据不一致性: ① 丟失修改:两个事务 T1 和 T2 读入同一数据…...
【软考网工笔记】计算机基础理论与安全——计算机硬件知识
计算机分级存储体系 计算机分级存储体系目前最常用的是三级存储体系。 CPU——CaChe(高速缓存)——主存——辅存 其中 Cache 是用于解决存取速度不够快,辅存是用于解决存储容量不够大,二者结合可在容量和速度实现提升的情况下尽可…...
SpringBoot 多种生产打包方式详解
Springboot 多种生产打包方式简介 生产上发布 Spring Boot 项目时,流程颇为繁琐且低效。但凡代码有一丁点改动,就得把整个项目重新打包部署,耗时费力不说,生成的 JAR 包还特别臃肿,体积庞大。每次更新项目,…...
WebSocket 安全实践:从认证到加密
在前三篇文章中,我们深入探讨了 WebSocket 的基础原理、服务端开发和客户端实现。今天,让我们把重点放在安全性上,看看如何构建一个安全可靠的 WebSocket 应用。我曾在一个金融项目中,通过实施多层安全机制,成功防御了多次恶意攻击尝试。 安全挑战 WebSocket 应用面临的主要安…...
实现单例模式的五种方式
如何实现一个单例 1、构造器需要私有化 2、提供一个私有的静态变量 3、暴露一个公共的获取单例对象的接口 需要考虑的两个问题 1、是否支持懒加载 2、是否线程安全 1、饿汉式 public class EagerSingleton {private static final EagerSingleton INSTANCE new EagerSi…...
【Go学习】-01-6-数据库泛型新特性
【Go学习】-01-6-数据库泛型新特性 1 数据库操作1.1 操作mysql1.1.1 Insert1.1.2 Select1.1.3 Update1.1.4 Delete1.1.5 sql事务 1.2 go操作Redis 2 泛型2.1 非泛型函数2.2 泛型函数2.3 泛型类型2.3.1 泛型结构体2.3.2 泛型接口 2.4 泛型约束2.5 泛型切片和映射2.5.1 泛型切片2…...
算法学习(22)—— BFS解决最短路问题
关于最短路问题 最短路问题是“图论”里非常重要的一类问题,涉及的内容非常多,在这个专题里,我们主要讲“边权为1的最短路问题”,因为这个比较基础比较简单而关于啥是“边权为1的最短路问题”,我们通过下面的例子来讲…...
【双层模型】考虑供需双侧的综合能源双层优化模型
目录 主要内容 内容研究 1.模型简介 2 程序释义 部分代码 运行结果 下载链接 主要内容 该程序实现一个综合能源系统的优化调度双层模型,上下层分别采用差分进化算法和规划算法进行求解。模型考虑了多种能源设备,包括燃气轮机、燃气锅炉、风电…...
【读书笔记/源码】How Tomcat Works 笔记- c11~c13
chapter11: standardwrapperchapter12: 无程序 第十章 安全性 servlet容器是通过一个名为验证器的阀来支持安全限制的。当servlet容器启动时,验证器阀会被添加到Context容器的管道中。 验证器阀会调用Context容器的领域对象的authenticate()方法,传入…...
Electron快速入门——跨平台桌面端应用开发框架
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...
Vision Transformer模型详解(附pytorch实现)
写在前面 最近,我在学习Transformer模型在图像领域的应用。图像处理任务一直以来都是深度学习领域的重要研究方向,而传统的卷积神经网络已在许多任务中取得了显著的成绩。然而,近年来,Transformer模型由于其在自然语言处理中的成…...
中国区域创新创业指数IRIEC数据(省级、地市级)1990-2020年-社科数据
中国区域创新创业指数IRIEC数据(省级、地市级)1990-2020年-社科数据https://download.csdn.net/download/paofuluolijiang/90028728 https://download.csdn.net/download/paofuluolijiang/90028728 中国区域创新创业指数(IRIEC)…...
Elasticsearch:减少 Elastic 容器镜像中的 CVE(常见的漏洞和暴露)
作者:来自 Elastic Maxime Greau 在这篇博文中,我们将讨论如何通过在 Elastic 产品中切换到最小基础镜像并优化可扩展漏洞管理程序的工作流程来显著减少 Elastic 容器镜像中的常见漏洞和暴露 (Common Vulnerabilities and Exposures - CVEs)。 基于 Chai…...
webpack02
webpack中常用loader postcss-loader 在css-loader之前,对css进行一些操作,,,比如统一加前缀,,或者是重置样式,,, 这个postcss-loader会自己去找 postcss工具࿰…...
腾讯云更改用户为root
最近买了台99元一年的2核的云服务器,方便学习一些java开发中间件,以及部署一些项目。 1.设置root用户密码 sudo passwd root 2.修改配置文件 ll /etc | grep ssh cd /etc/ssh/ ls vim sshd_config 输入/PasswordAuthentication 寻找 输入:set nu 再按下…...
Excel导入导出-若依版本
最终效果 1、导出 1、在实体类上加注解 Excel(name “客户类型名称”) ToString AllArgsConstructor NoArgsConstructor public class UserType extends BaseEntity2 implements Serializable {Excel(name "客户类型ID", cellType Excel.ColumnType.NUMERIC…...
【Qt】快速添加对应类所需的头文件包含
快速添加对应类所需的头文件包含 一,简介二,操作步骤 一,简介 本文介绍一下,如何快速添加对应类所需要包含的头文件,可以提高开发效率,供参考。 二,操作步骤 以QTime类为例: 选中…...
基于服务器部署的综合视频安防系统的智慧快消开源了。
智慧快消视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。国产化人工智能“…...
浅谈棋牌游戏开发流程七:反外挂与安全体系——守护游戏公平与玩家体验
一、前言:为什么反外挂与安全这么重要? 对于任何一款线上棋牌游戏而言,公平性和玩家安全都是最重要的核心要素之一。如果游戏环境充斥着各式各样的外挂、作弊方式,不仅会毁坏玩家体验,更会导致游戏生态崩塌、口碑下滑…...
Laravel操作ElasticSearch
在Laravel项目中操作ElasticSearch可以通过以下步骤来实现,通常会借助相应的ElasticSearch客户端扩展包。 ### 安装ElasticSearch客户端包 在Laravel项目中,常用的是 elasticsearch/elasticsearch 这个PHP客户端库来与ElasticSearch进行交互,…...
缓存-文章目录
关于缓存系列文章: 缓存学习总结1(缓存分类) 缓存学习总结2(服务器本地缓存) 缓存学习总结3(服务器内存缓存)推荐使用 缓存学习总结4(分布式缓存) 关于redis系列文章…...
安装教程:慧集通集成平台(DataLinkX)智能体客户端安装操作(Linux/windows/mac)
1.下载客户端 使用提供的账号登录集成平台后台(https://www.datalinkx.cn/),点击左侧菜单栏【智能体】→【智能体】进入到智能体列表界面,在该界面我们找到功能栏中的下载按钮点击则会弹出下载界面,在该界面我们可以选择不同的系统操作系统来下载对应版…...