在性能优化中一个最具参考价值的属性是FPS:FramesPerSecond,其实就是屏幕刷新率,苹果的iphone推荐的刷新率是60Hz,也就是说GPU每秒钟刷新屏幕60次,这每刷新一次就是一帧frame,FPS也就是每秒钟刷新多少帧画面。静止不变的页面FPS值是0,这个值是没有参考意义的,只有当页面在执行动画或者滑动的时候,FPS值才具有参考价值,FPS值的大小体现了页面的流畅程度高低,当低于45的时候卡顿会比较明显。
图层混合:
每一个 layer是一个纹理,所有的纹理都以某种方式堆叠在彼此的顶部。对于屏幕上的每一个像素,GPU需要算出怎么混合这些纹理来得到像素 RGB的值。
当Sa= 0.5时,RGB值为(0.5, 0, 0),可以看出,当两个不是完全不透明的 CALayer覆盖在一起时,GPU大量做这种复合操作,随着这中操作的越多,GPU越忙碌,性能肯定会受到影响。
公式:
R = S + D * ( 1 – Sa )
结果的颜色是源色彩(顶端纹理)+目标颜色(低一层的纹理)*(1-源颜色的透明度)。
当Sa= 1时,R = S,GPU将不会做任何合成,而是简单从这个层拷贝,不需要考虑它下方的任何东西(因为都被它遮挡住了),这节省了 GPU相当大的工作量。
ARC管理内存
2、在正确的地方使用 reuseIdentifier
3、尽量把views设置为透明
4、避免过于庞大的 XIB
5、不要阻塞主线程
6、在ImageViews中调整图片大小。如果要在 UIImageView中显示一个来自 bundle的图片,你应保证图片的大小和 UIImageView的大小相同。在运行中缩放图片是很耗费资源的,特别是 UIImageView嵌套在
UIScrollView中的情况下。如果图片是从远端服务加载的你不能控制图片大小,比如在下载前调整到合适大
小的话,你可以在下载完成后,最好是用 backgroundthread,缩放一次,然后在 UIImageView中使用缩放后的图片。
7、选择正确的Collection。
Arrays:有序的一组值。使用 index来 lookup很快,使用 value lookup很慢,插入/删除很慢。
Dictionaries:存储键值对。用键来查找比较快。
Sets:无序的一组值。用值来查找很快,插入/删除很快。
gzip压缩。app可能大量依赖于服务器资源,问题是我们的目标是移动设备,因此你就不能指望网
络状况有多好。减小文档的一个方式就是在服务端和你的 app中打开 gzip。这对于文字这种能有更高压缩率的数据来说会有更显著的效用。
iOS已经在 NSURLConnection中默认支持了gzip压缩,当然 AFNetworking这些基于它的框架亦然。
(lazy load) Views
view意味着更多的渲染,也就是更多的 CPU和内存消耗,对于那种嵌套了很多view在
UIScrollView里边的 app更是如此。
UITableView和 UICollectionView的操作:不要一次创建所有的 subview,
而是当需要时才创建,当它们完成了使命,把他们放进一个可重用的队列中。这样的话你就只需要在滚动发生时创建你的 views,避免了不划算的内存分配。
Cache, Cache,还是 Cache!
UITableView的行高。
NSCache和 NSDictionary类似,不同的是系统回收内存的时候它会自动删掉它的内容。
bundle保持合适的大小。
4、处理内存警告.移除对缓存,图片 object和其他一些可以重创建的 objects的 strong references.
5、重用大开销对象
6、一些 objects的初始化很慢,比如 NSDateFormatter和 NSCalendar。然而,你又不可避免地需要使用它们,比如从 JSON或者 XML中解析数据。想要避免使用这个对象的瓶颈你就需要重用他们,可以通过添加属性到你的 class里或者创建静态变量来实现。
7、避免反复处理数据.在服务器端和客户端使用相同的数据结构很重要。
8、选择正确的数据格式.解析 JSON会比XML更快一些,JSON也通常更小更便于传输。从 iOS5起有了官方内建的 JSON deserialization就更加方便使用了。但是 XML也有 XML的好处,比如使用 SAX来解析 XML就像解析本地文件一样,你不需像解析 json一样等到整个文档下载完成才开始解析。当你处理很大的数据的时候就会极大地减低内存消耗和增加性能。
9、正确设定背景图片
view中添加一个 UIImageView作为一个子 View
view的背景图,你就需要用 UIColor的 colorWithPatternImage来做了,它会更快地渲染
也不会花费很多内存。
Web特性。想要更高的性能你就要调整下你的HTML了。第一件要做的事就是尽可能移除不必要的javascript,避免使用过大的框架。能只用原生 js就更好了。尽可能异步加载例如用户行为统计 script这种不影响页面表达的 javascript。注意你使用的图片,保证图片的符合你使用的大小。
11、Shadow Path。CoreAnimation不得不先在后台得出你的图形并加好阴影然后才渲染,这开销是很大的。使用 shadowPath的话就避免了这个问题。使用 shadow path的话 iOS就不必每次都计算如何渲染,它使用一个预先计算好的路径。但问题是自己计算 path的话可能在某些 View中比较困难,且每当 view的 frame变化的时候你都需要去 update shadow path.
12、优化 Table View
reuseIdentifier来重用 cells
view opaque,包括 cell自身
cell内现实的内容来自web,使用异步加载,缓存请求结果
shadowPath来画阴影
subviews的数量
cellForRowAtIndexPath:,如果你需要用到它,只用-一次然后缓存结果
rowHeight, sectionFooterHeight和 sectionHeaderHeight来设定固定的高,不要请求 delegate
NSUserDefaults的问题是什么?虽然它很 nice也很便捷,但是它只适用于小数据,比如一些简单的布尔型的设置选项,再大点你就要考虑其它方式了
XML这种结构化档案呢?总体来说,你需要读取整个文件到内存里去解析,这样是很不经济的。使用SAX又是一个很麻烦的事情。
NSCoding?不幸的是,它也需要读写文件,所以也有以上问题。
SQLite或者 Core Data比较好。使用这些技术你用特定的查询语句就能只加载你需要的对象。
SQLite和 Core Data是很相似的。他们的不同在于具体使用方法。
Core Data代表一个对象的 graph model,但 SQLite就是一个 DBMS。
Apple在一般情况下建议使用 Core Data,但是如果你有理由不使用它,那么就去使用更加底层的 SQLite吧。
SQLite,你可以用 FMDB这个库来简化SQLite的操作,这样你就不用花很多经历了解 SQLite的 C API了。
首先作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的ioser公众号:编程大鑫,不管你是小白还是大牛都欢迎入驻 ,让我们一起进步,共同发展!(会免费提供一些群主收藏的免费学习书籍资料以及整理好的几百道面试题和答案文档!)1、加速启动时间。快速打开
app是很重要的,特别是用户第一次打开它时,对 app来讲,第一印象太太太重要了。你能做的就是使它尽可能做更多的异步任务,比如加载远端或者数据库数据,解析数据。避免过于庞大的XIB,因为他们是在主线程上加载的。所以尽量使用没有这个问题的 Storyboards吧!一定要把设备从Xcode断开来测试启动速度
2、使用 Autorelease Pool。NSAutoreleasePool负责释放 block中的 autoreleased objects。一般情况下它会自动被UIKit调用。但是有些状况下你也需要手动去创建它。假如你创建很多临时对象,你会发现内存一直在减少直到这些对象被release的时候。这是因为只有当UIKit用光了 autorelease pool的时候 memory才会被释放。消息是你可以在你自己的@autoreleasepool里创建临时的对象来避免这个行为。
3、选择是否缓存图片。常见的从 bundle中加载图片的方式有两种,一个是用imageNamed,二是用imageWithContentsOfFile,第一种比较常见一点。
4、避免日期格式转换。如果你要用 NSDateFormatter来处理很多日期格式,应该小心以待。就像先前提到的,任何时候重用NSDateFormatters都是一个好的实践。如果你可以控制你所处理的日期格式,尽量选择Unix时间戳。你可以方便地从时间戳转换到 NSDate:
这样会比用 C来解析日期字符串还快!需要注意的是,许多web API会以微秒的形式返回时间戳,因为这种格式在 javascript中更方便使用。记住用dateFromUnixTimestamp之前除以 1000就好了。
平时你是如何对代码进行性能优化的?
Analyze工具,以及运行时 Profile工具,通过 Xcode工具栏中Product->Profile可以启动,比如测试程序启动运行时间,当点击 Time Profiler应用程序开始运行后.就能获取到整个应用程序运行消耗时间分布和百分比.为了保证数据分析在统一使用场景真实需要注意一定要使用真机,因为此时模拟器是运行在 Mac上,而 Mac上的 CPU往往比 iOS设备要快。
iOS的苹果工程师门设计了一个“看门狗”的机制。在不同的场景下,“看门狗”会监测应用的性能。如果超出了该场景所规定的运行时间,“看门狗”就会强制终结这个应用的进程。开发者们在crashlog里面,会看到诸如 0x8badf00d这样的错误代码。
Table View
reuseIdentifier来重用 cells
view opaque,包括cell自身
cell内现实的内容来自 web,使用异步加载,缓存请求结果减少subviews的数量
cellForRowAtIndexPath:,如果你需要用到它,只用一次然后缓存结果
rowHeight, sectionFooterHeight和sectionHeaderHeight来设定固定的高,不要请求 delegate
UIImage加载图片性能问题
imagedNamed初始化
imageWithContentsOfFile初始化
imageNamed默认加载图片成功后会内存中缓存图片,这个方法用一个指定的名字在系统缓存中查找并返回一个图片对象.如果缓存中没有找到相应的图片对象,则从指定地方加载图片然后缓存对象,并返回这个图片对象.
imageWithContentsOfFile则仅只加载图片,不缓存.
viewWillAppear中做费时的操作:viewWillAppear:在 view显示之前被调用,出于效率考虑,方法中不要处理复杂费时操作;在该方法设置 view的显示属性之类的简单事情,比如背景色,字体等。否则,会明显感觉到 view有卡顿或者延迟。
reuseIdentifier:table view用 tableView:cellForRowAtIndexPath:为 rows分配
cells的时候,它的数据应该重用自 UITableViewCell。
views设置为透明:如果你有透明的 Views你应该设置它们的 opaque属性为 YES。系统用一个最优的方式渲染这些 views。这个简单的属性在 IB或者代码里都可以设定。
XIB:尽量简单的为每个Controller配置一个单独的XIB,尽可能把一个 ViewController的 view层次结构分散到单独的XIB中去,当你加载一个引用了图片或者声音资源的 nib时,nib加载代码会把图片和声音文件写进内存。
UIKit在主线程上做所有工作,渲染,管理触摸反应,回应输入等都需要在它上面完成,大部分阻碍主进程的情形是你的 app在做一些牵涉到读写外部资源的 I/O操作,比如存储或者网络。
Image Views中调整图片大小
Instrument优化动画性能的经历吧(别问我什么是 Instrument)
facebook启动时间优化
1.瘦身请求依赖
2.UDP启动请求先行缓存
3.队列串行化处理启动响应
Memory Leaks
Alloctions
Analyse
Debug Memory Graph
MLeaksFinder
Lak Memory这种是忘记 Release操作所泄露的内存。
Abandon Memory这种是循环引用,无法释放掉的内存。
首先上面的方式是不可取的,会触发离屏渲染。
cornerRadius解决问题,就不用优化。
masksToBounds,可以参考圆角视图的数量,如果数量较少(一页只有几个)也可以考虑不用优化。
UIImageView的圆角通过直接截取图片实现,其它视图的圆角可以通过 Core Graphics画出圆角矩形实现。
CPU、GPU的工作,从这两个大的方面去提升性能。
CPU:对象的创建和销毁、对象属性的调整、布局计算、文本的计算和排版、图片的格式转换和解码、图像的绘制
GPU:纹理的渲染
卡顿优化在CPU层面
CALayer取代 UIView
UIView的相关属性,比如 frame、bounds、transform等属性,尽量减少不必要的修改
Autolayout会比直接设置 frame消耗更多的 CPU资源
size最好刚好跟 UIImageView的 size保持一致
GPU能处理的最大纹理尺寸是 4096x4096,一旦超过这个尺寸,就会占用 CPU资源进行处理,所以纹理尽量不要超过这个尺寸
alpha<1),不透明的就设置 opaque为 YES
CoreText排版的结果、单个控件的高度、cell整体的高度提前计算好,将其存储在模型的属性中。需要使用时,直接从模型中往外取,避免了计算的过程。尽量少用 UILabel,可以使用 CALayer。避免使用 AutoLayout的自动布局技术,采取纯代码的方式
2.预渲染,提前绘制
例如圆形的图标可以提前在,在接收到网络返回数据时,在后台线程进行处理,直接存储在模型数据里,回到主线程后直接调用就可以了避免使用 CALayer的 Border、corner、shadow、mask等技术,这些都会触发离屏渲染。
3.异步绘制
4.全局并发线程
5.高效的图片异步加载
CPU、GPU的功耗。
·尽量少用定时器。
·优化 I/O操作。
o 不要频繁写入小数据,而是积攒到一定数量再写入
o 读写大量的数据可以使用 Dispatch_io,GCD内部已经做了优化。
o 数据量比较大时,建议使用数据库
XML -> JSON -> ProtoBuf),如果可能建议使用 ProtoBuf。
o 如果请求的返回数据相同,可以使用 NSCache进行缓存
o 使用断点续传,避免因网络失败后要重新下载。
o 网络不可用的时候,不尝试进行网络请求
o 长时间的网络请求,要提供可以取消的操作
o 采取批量传输。下载视频流的时候,尽量一大块一大块的进行下载,广告可以一次下载多个
CLLocationManager的 requestLocation方法。定位完成后,会自动让定位硬件断电
o 如果不是导航应用,尽量不要实时更新位置,定位完毕就关掉定位服务
o 尽量降低定位精度,比如尽量不要使用精度最高的 kCLLocationAccuracyBest
o 需要后台定位时,尽量设置 pausesLocationUpdatesAutomatically为 YES,如果用户不太可能移动的时候系统会自动暂停位置更新
o 尽量不要使用startMonitoringSignificantLocationChanges,优先考虑startMonitoringForRegion:
Strip Linked Product、Make Strings Read-Only、Symbols Hidden by Default设置为 YES
Enable C++ Exceptions、Enable Objective-C Exceptions设置为 NO, Other C Flags添加 -fno-exceptions
AppCode检测未使用的代码:菜单栏 -> Code -> Inspect Code
LLVM插件检测出重复代码、未被调用的代码
maskToBounds并用才会触发)
CPU GPU在绘制渲染视图时做了大量的工作。离屏渲染发生在 GPU层面上,会创建新的渲染缓冲区,会
触发 OpenGL的多通道渲染管线,图形上下文的切换会造成额外的开销,增加 GPU工作量。如果 CPU GPU累计耗时 16.67毫秒还没有完成,就会造成卡顿掉帧。
圆角属性、蒙层遮罩都会触发离屏渲染。指定了以上属性,标记了它在新的图形上下文中,在未愈合之前,不可以用于显示的时候就出发了离屏渲染。
OpenGL中,GPU有 2种渲染方式
On-Screen Rendering:当前屏幕渲染,在当前用于显示的屏幕缓冲区进行渲染操作
Off-Screen Rendering:离屏渲染,在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作
On-Screen)切换到离屏(Off-Screen);等到离屏渲染结束以后,将离屏缓冲区的渲染结果显示到屏幕上,又需要将上下文环境从离屏切换到当前屏幕
layer.shouldRasterize = YES
layer.mask
layer.masksToBounds = YES、layer.cornerRadius大于 0
CoreGraphics绘制裁剪圆角,或者叫美工提供圆角图片
layer.shadowXXX,如果设置了 layer.shadowPath就不会产生离屏渲染
debug-选中 color Offscreen - Renderd离屏渲染的图层高亮成黄可能存在性能问题
2、真机Instrument-选中Core Animation-勾选Color Offscreen-Rendered Yellow
离屏渲染的触发方式
设置了以下属性时,都会触发离屏绘制:
1、layer.shouldRasterize(光栅化)
光栅化概念:将图转化为一个个栅格组成的图象。
光栅化特点:每个元素对应帧缓冲区中的一像素。
2、masks(遮罩)
3、shadows(阴影)
4、edge antialiasing(抗锯齿)
5、group opacity(不透明)
6、复杂形状设置圆角等
7、渐变
8、drawRect
例如我们日程经常打交道的 TableViewCell,因为TableViewCell的重绘是很频繁的(因为 Cell的复用),如果Cell的内容不断变化,则 Cell需要不断重绘,如果此时设置了 cell.layer可光栅化。则会造成大量的离屏渲染,降低图形性能。
如果将不在GPU的当前屏幕缓冲区中进行的渲染都称为离屏渲染,那么就还有另一种特殊的“离屏渲染”方式:CPU渲染。如果我们重写了 drawRect方法,并且使用任何 Core Graphics的技术进行了绘制操作,就涉及到了CPU渲染。整个渲染过程由 CPU在 App内同步地完成,渲染得到的 bitmap最后再交由 GPU用于显示。
现在摆在我们面前得有三个选择:当前屏幕渲染、离屏渲染、CPU渲染,该用哪个呢?这需要根据具体的
使用场景来决定。
尽量使用当前屏幕渲染
鉴于离屏渲染、CPU渲染可能带来的性能问题,一般情况下,我们要尽量使用当前屏幕渲染。
离屏渲染 VS CPU渲染
由于 GPU的浮点运算能力比 CPU强,CPU渲染的效率可能不如离屏渲染;但如果仅仅是实现一个简单的效果,直接使用CPU渲染的效率又可能比离屏渲染好,毕竟离屏渲染要涉及到缓冲区创建和上下文切换等耗时操作
UIButton的 masksToBounds = YES又设置 setImage、setBackgroundImage、[buttonsetBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"btn_selected"]]];
下发生离屏渲染,但是[button setBackgroundColor:[UIColor redColor]];是不会出现离屏渲染的
关于 UIImageView,现在测试发现(现版本: iOS10),在性能的范围之内,给 UIImageView设置圆角是不会触发离屏渲染的,但是同时给 UIImageView设置背景色则肯定会触发.触发离屏渲染跟 png.jpg格式并无关联
日常我们使用layer的两个属性,实现圆角
imageView.layer.cornerRaidus = CGFloat(10);
imageView.layer.masksToBounds = YES;
这样处理的渲染机制是GPU在当前屏幕缓冲区外新开辟一个渲染缓冲区进行工作,也就是离屏渲染,这会给我们带来额外的性能损耗。如果这样的圆角操作达到一定数量,会触发缓冲区的频繁合并和上下文的频繁切换,性能的代价会宏观地表现在用户体验上——掉帧
debug-选中 color blended layers红色区域表示图层发生了混合
2、Instrument-选中Core Animation-勾选Color Blended Layers
避免图层混合:
1、确保控件的opaque属性设置为true,确保 backgroundColor和父视图颜色一致且不透明
2、如无特殊需要,不要设置低于 1的alpha值
3、确保UIImage没有 alpha通道
UILabel图层混合解决方法:
iOS8以后设置背景色为非透明色并且设置 label.layer.masksToBounds=YES让label只会渲染她的实际 size区域,就能解决UILabel的图层混合问题
iOS8之前只要设置背景色为非透明的就行
为什么设置了背景色但是在 iOS8上仍然出现了图层混合呢?
UILabel在 iOS8前后的变化,在 iOS8以前,UILabel使用的是 CALayer作为底图层,而在 iOS8开始,UILabel的底图层变成了_UILabelLayer,绘制文本也有所改变。在背景色的四周多了一圈透明的边,而这一圈透明的边明显超出了图层的矩形区域,设置图层的 masksToBounds为 YES时,图层将会沿着 Bounds进行裁剪图层混合问题解决了.
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------