ToB企服应用市场:ToB评测及商务社交产业平台
标题:
你怎么看 App响应时间优化这事?,HarmonyOS鸿蒙进阶之光pdf下载
[打印本页]
作者:
种地
时间:
2024-10-1 14:35
标题:
你怎么看 App响应时间优化这事?,HarmonyOS鸿蒙进阶之光pdf下载
先自我先容一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数步调员,想要提拔技能,每每是本身摸索成长,但本身不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新HarmonyOS鸿蒙全套学习资料》,初志也很简单,就是渴望能够资助到想自学提拔又不知道该从何学起的朋友。
既有恰当小白学习的零底子资料,也有恰当3年以上经验的小伙伴深入学习提拔的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比较多,这里只是将部门目录截图出来,全套包罗大厂面经、学习条记、源码讲义、实战项目、大纲门路、讲解视频,并且后续会连续更新
假如你需要这些资料,可以添加V获取:vip204888 (备注鸿蒙)
正文
}
// mDelayTasks非空时返回ture表示下次继续实行,为空时返回false体系会移除该IdleHandler不再实行
return !mDelayTasks.isEmpty();
};
public DelayTaskQueue addTask(Runnable task) {
mDelayTasks.add(task);
return this;
}
public void start() {
Looper.myQueue().addIdleHandler(mIdleHandler);
}
}
2.2 资源加载
1.懒加载
2.分段加载(部门加载)
3.预加载(数据、布局页面等)
2.2.1 懒加载
对于一些不常用或者不重要的数据、图片、控件以及其他一些资源,我们可以在用到时再进行加载。
1.数据懒加载
kotlin中的lazy标签:修饰val变量,步调第一次使用到这个变量(或者对象)时再初始化。
Map、List和SharedPreferences等大数据的耽误初始化。
private Map getSystemSettings() {
if (mSettingMap == null) {
mSettingMap = initSystemSettings();
}
return mSettingMap;
}
2.图片资源懒加载
对于不常用的图片,可以使用云端图片的资源url来替换。
对于非步调预置的图片(本地图片文件或者云端图片),用到时再加载。
3.控件懒加载
使用ViewStub进行布局的耽误加载。
使用ViewPager2+Fragment进行Fragment的懒加载。
使用RecyclerView替换ListView。
2.2.2 分段加载
分段加载常见应用于大数据的加载,这里包括大图和长视频等多媒体资源的加载。做到用到哪,加载到哪,完全不必要等全部加载完才给用户使用。
1.大图的分段加载:对于大图,我们可以将其按肯定尺寸进行切分,分割成一块一块的小瓦片,然后设定一个预览预加载范围,用户预览到那里我们就加载到那里。(就雷同地图的加载)
2.长视频的分段加载:对于长视频,我们可以将其按时间片进行拆分,并设置一个加载缓存池。这样用户欣赏一个长视频时,就可以快速打开加载。
3.大文件或者长WebView的分段加载:对于一些阅读类的app,经常会碰到大文件和长WebView的加载,这里我们也可以同理对其进行拆分处理。
2.2.3 预加载
分段加载常和预加载一起组合使用。对于一些加载非常耗时的内容,我们可以将加载机遇提前,从而减小用户感知的加载时间。
预加载的本质是提前加载,这样这个提前加载的机遇就非常的关键和重要。由于预加载机遇假如太晚,险些看不出效果;但是假如预加载的机遇过早,有可能抢占其他模块资源,造成资源紧张。
那么我们何时可以触发预加载,预加载的机遇是什么呢?下面我举几个简单的例子。
1.用户操纵时。假如用户点击了第2章,我们就开始预加载下一章和上一章;用户上滑到了第3页,我们预加载第4页,用户下滑到第5页,我们预加载第4页.
2.应用空闲时。例如之前说的IdleHandler。或者在onUserInteraction中监听用户的操纵,一段时间没有操纵即视为空闲。
3.耗时等待时。对于一些常见的耗时操纵,我们可以在其开始时,并行进行一些预加载操纵,从而提高时间的利用率。例如Activity的创建比较耗时,我们可以在startActivity前就开始预加载数据,这样Activity创建完之后有可能数据就已经加载好了,直接可以拿来渲染。例如一些有开屏广告的app,可以在广告开始时,同步进行一些数据资源的预加载。
2.3 数据结构
1.数据结构优化(空间大小、读取速率、复用性、扩展性)。
2.数据缓存(内存缓存、磁盘缓存、网络缓存),分段缓存。这里可以参考glide.
3.锁优化(减少过度锁,避免死锁),灰心锁/乐观锁。
4.内存优化,避免内存抖动,频繁GC(尤其关注bitmap)
2.3.1 数据结构优化
不同的数据结构有不同的使用场景,选择恰当的数据结构能够事半功倍。
1.ArrayList和LinkedList:
ArrayList:底层数据结构是数组,查询快、增删慢。
LinkedList:底层数据结构是链表,查询慢、增删快。
2.HashMap和SparseArray:
HashMap:底层数据结构是数组和链表(或红黑树)的组合,结合了ArrayList和LinkedList的优点,查询快、增删也快。但是扩容很耗性能,且空间利用率不高(75%),浪费内存。
SparseArray:底层数据结构是双数组,一个数组存key,一个数组存value。使用二分法查询进行优化,在数据量小(一百条以下)的情况下,速率和HashMap相当,但是空间利用率大大提拔。
ArrayMap:底层数据结构是双数组,一个数组存key的hash值,一个数组存value。设计与SparseArray雷同,在数据量小的情况下,可完全替换HashMap。
3.Set: 包管每个元素都必须是唯一的。
4.TreeSet和TreeMap:有序的集合,包管存放的元素是排过序的,速率慢于HashSet和HashMap。
可以看到,在不考虑空间利用率的情况下,HashMap的性能是不错的。
但是由于存在初始化大小和扩展因子对其性能有所影响,我们在使用时,尽量根据实际需要设置合理的初始化大小:避免设置小了扩容带来性能消耗,设置大了造成空间浪费。
由于HashMap的默认扩容因子是0.75,假如你实际使用的数量是8,那你初始化大小就设置16;假如你实际使用的数量是60,那你初始化大小就设置128。
2.3.2 数据缓存
对于一些厘革不是很频繁的数据资源,我们可以将其缓存下来。这样我们下次需要使用它们的时候,就可以直接读取缓存,这样极大地减少了加载和渲染所需要的时间。
一般意义上的缓存,按读取的时间由快到慢,我们可分为内存缓存、磁盘缓存、网络缓存。
内存缓存,就是存储在内存中,我们可以直接读取使用。而假如从界面渲染的角度,我们又可以将内存缓存分为Active(活跃/正在体现)缓存和InActive(非活跃/不可体现)缓存。
磁盘缓存,就是存储在磁盘文件中,每次读取都需要将磁盘文件内容读取到内存中,方可使用。
网络缓存,就是存储在远端服务器中,每次读取需要我们进行一次网络哀求。一般来说,我们也可以将一次网络缓存哀求到的数据缓存到磁盘中,将网络缓存转化为磁盘缓存,通过减少网络哀求,来提拔读取速率。
某种意义上来说,内存缓存、磁盘缓存和网络缓存,它们又是可以相互转化的,一般来说,我们会将网络缓存->磁盘缓存->内存缓存,进行使用,从而提拔读取速率。
具体我们可以参考glide框架和RecyclerView的实现原理。
2.3.3 锁优化
锁是我们解决并发的重要本领,但是假如滥用锁的话,很可能造成实行服从下降,更严重的可能造成死锁等无法挽回的场景。
当我们需要处理高并发的场景时,同步调用尤其需要考量锁的性能损耗:
能用无锁数据结构,就不要用锁。
缩小锁的范围。能锁区块,就不要锁住方法体;能用对象锁,就不要用类锁。
那么我们具体应该怎么做呢?下面我简单讲几个例子。
1.使用乐观锁取代灰心锁,轻量级锁取代重量级锁。
利用CAS机制, 全称是Compare And Swap,即先比较,然后再更换。就是每次实行或者修改某个变量时,我们都会将新旧值进行比较,假如发生偏移了就更新。这就比如在一些无锁的数据库中,每次的数据库操纵都会携带一个唯一的版本号,每次进行数据库修改的时候都会对比一下数据库记载和操纵哀求的版本号,假如版本号是最新的版本号,则进行修改,否则丢弃。
需要注意的是,CAS必须借助volatile才气读取到共享变量的最新值来实现【比较并互换】的效果,由于volatile会包管变量的可见性。
在Java中,JDK给我们默认提供了一些CAS机制实现的原子类,如AtomicInteger、AtomicReference等。
2.缩小同步范围,避免直接使用synchronized,即使使用也要尽量使用同步块而不是同步方法。多使用JDK提供给我们的同步工具:CountDownLatch,CyclicBarrier,ConcurrentHashMap。
3.针对不同使用场景,使用不同类型的锁。
针对并发读多,写少的,我们可以使用读写锁(多个读锁不互斥,读锁与写锁互斥):ReentrantReadWriteLock,CopyOnWriteArrayList,CopyOnWriteArraySet。
针对某一个并发操纵通常由某一特定线程实行时,可尝试使用方向锁(方向于第一个得到它的线程)。
针对存在大量并发资源竞争的场景,推荐使用重量级锁synchronized。
2.3.4 内存优化
内存优化的焦点是避免内存抖动。不合理的内存分配、内存走漏、对象的频繁创建和销毁,都会导致内存发生抖动,最终导致体系的频繁GC。
频繁的GC,必定会导致体系运行服从的下降,严重的可能会导致页面卡顿,造成欠好的用户体验。那么我们应该着手从哪些地方进行优化呢?
解决应用的内存走漏问题。这里我们可以使用LeakCanary 或者 Android Profile 等工具来查抄我们查询可能存在的内存走漏。
平常编码应当注意避免内存走漏。如避免全局静态变量和常量、单例持有资源对象(Activity,Fragment,View等),资源使用完立即开释或者recycle(回收)等。
避免创建大内存对象,频繁创建和开释对象(尤其是在循环体内),频繁创建的对象需要考虑复用或者使用缓存。
加载图片可以适当低落图片质量,小图标尽量使用SVG,大图/复杂的图片考虑使用webp。尽量使用图片加载框架,如glide,这些框架都会帮我们进行加载优化。
避免大量bitmap的绘制。
避免在自界说View的onMeasure、onLayout和onDraw中创建对象。
使用SpareArray、ArrayMap替换HashMap。
避免进行大量的字符串操纵,特殊是序列化和反序列化。不要使用+(加号)进行字符串拼接。
使用线程池(可设置适当的最大线程池数)实行线程任务,避免大量Thread的创建及走漏。
2.4 线程/IO
1.线程优化(统一、优先级调度、任务特性)
2.IO优化(网络IO和磁盘IO),焦点是减少IO次数
网络:哀求合并,哀求链路优化,哀求体优化,系列化和反序列化优化,哀求复用等。
磁盘:文件随机读写、SharePreference读写等(例如对于读多写少的,可使用内存缓存)
3.log优化(循环中的log打印,不必要的log打印,log品级)
2.4.1 线程优化
当我们创建一个线程时,需要向体系申请资源,分配内存空间,这是一笔不小的开销,所以我们平常开发的过程中都不会直接操纵线程,而是选择使用线程池来实行任务。所以线程优化的本质是对线程池的优化。
线程池使用的最大问题就在于假如线程池设置不对的话,很轻易被人滥用,引发内存溢出的问题。而且通常一个应用会有多个线程池,不同功能、不同模块乃至是不同三方库都会有本身的线程池,这样各人各用各的,就很难做到资源的协调统一,劲不往一处使。
那么我们应该怎样进行线程池优化呢?
1.建立主线程池+副线程池的组合线程池,由线程池管理者统一协调管理。主线程池负责优先级较高的任务,副线程池负责优先级不高以及被主线程池拒绝降级下来的任务。
这里实行的任务都需要设置优先级,任务优先级的调度通过PriorityBlockingQueue队列实现,以下是主副线程池的设置,仅供参考:
主线程池:焦点线程数和最大线程数:2n(n为CPU焦点数),60s keepTime,PriorityBlockingQueue(128)。
副线程池:焦点线程数和最大线程数:n(n为CPU焦点数),60s keepTime,PriorityBlockingQueue(64)。
2.使用Hook的方式,收集应用内所以使用newThread方法的地方,改为由线程池管理者统一协调管理。
3.将所有提供了设置线程池接口的第三方库,通过其开放的接口,设置为线程池管理者管理。没有提供设置接口的,考虑更换库或者插桩的方式,更换线程池的使用。
2.4.2 IO优化
IO优化的焦点是减少IO次数。
1.网络哀求优化。
避免不必要的网络哀求。对于那些非必要实行的网络哀求,可以延时哀求或者使用缓存。
对于需要进行多次串行网络哀求的接口进行优化整合,控制好哀求接口的粒度。比如背景有获取用户信息的接口、获取用户推荐信息的接口、获取用户账户信息的接口。这三个接口都是必要的接口,且存在先后关系。假如依次进行三次哀求,那么时间根本上都花在网络传输上,尤其是在网络不稳固的情况下耗时尤为明显。但假如将这三个接口整合为获取用户的启动(初始化)信息,这样数据在网络中传输的时间就会大大节省,同时也能提高接口的稳固性。
2.磁盘IO优化
避免不必要的磁盘IO操纵。这里的磁盘IO包括:文件读写、数据库(sqlite)读写和SharePreference等。
对于数据加载,选择合适的数据结构。可以选择支持随机读写、延时剖析的数据存储结构以替换SharePreference。
避免步调实行出现大量的序列化和反序列化(会造成大量的对象创建)。
2.5 页面渲染
下面是我简单列举的几点加快页面渲染的方法,相信各人或多或少都用过,这里我就不具体阐述了:
1.低落布局层级、减少嵌套、避免过度渲染(背景)(merge,ConstraintLayout)
2.页面复用(include)
3.页面懒加载
4.布局耽误加载(ViewStub)
5.inflate优化(布局预加载+异步加载,动态new控件/X2C)
6.动画优化(注意动画的实行耗时和内存占用,不可见时暂停动画,可见时再规复动画)
7.自界说view优化(减少onDraw、onLayout、onMeasure的对象创建和实行耗时)
8.bitmap和canvas优化(bitmap大小、质量、压缩、复用;canvas复用:clipRect,translate)
9.RecycleView优化(减少刷新次数,缓存复用)
实在想要全面掌握好 Android 性能优化的话,这些知识点你必须要有所了解,如:
内存优化、网络优化、卡顿优化、存储优化……等,为了让各人一次都可以了解全,所以将其整合成名为《Android 性能优化焦点知识点手册》,各人可以参考下:
网上学习资料一大堆,但假如学到的知识不成体系,碰到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提拔。
需要这份体系化的资料的朋友,可以添加V获取:vip204888 (备注鸿蒙)
一个人可以走的很快,但一群人才气走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎参加我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、口试辅导),让我们一起学习成长!
d 性能优化的话,这些知识点你必须要有所了解,如:
内存优化、网络优化、卡顿优化、存储优化……等,为了让各人一次都可以了解全,所以将其整合成名为《Android 性能优化焦点知识点手册》,各人可以参考下:
网上学习资料一大堆,但假如学到的知识不成体系,碰到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提拔。
需要这份体系化的资料的朋友,可以添加V获取:vip204888 (备注鸿蒙)
[外链图片转存中…(img-FoF81kJr-1713173675765)]
一个人可以走的很快,但一群人才气走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎参加我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、口试辅导),让我们一起学习成长!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4