性能优化
<p>场景:同进程下,出现同时运行的动效,特别是全屏大图,对GPU渲染造成巨大负担</p><p><img src="https://img2024.cnblogs.com/blog/583064/202603/583064-20260330135009317-955259232.png"></p>
<p>明显看出,动效过程中,trace显示异常,两个draw出现,图片大小为3200x2000,都在同一个render跟ui thread下进行提交渲染,(由于图片比较大,而且不能压缩跟裁剪处理),处于串行工作造成掉帧</p>
<h4>方案一</h4>
<p>针对这种情况,首先尝试利用Glide中的set(<strong>Downsampler.ALLOW_HARDWARE_CONFIG</strong>, true)api来优化,看下效果</p>
<p><img src="https://img2024.cnblogs.com/blog/583064/202603/583064-20260330140214978-486738626.png"></p>
<p>可以看到,trace中已经没有upload图片了,这个api的用处,是用来缓存图片数据到GPU存储中的,这里的缓存不是指内存</p>
<blockquote>
<p>在图片绘制过程中,每次图片动效,比如全屏轮播,都会带来GPU的重新渲染,跟本地是否缓存图片没关系,普通位图会在应用内存和 GPU 显存中各存一份像素数据</p>
<p>每次绘制时从 CPU 内存,将图片数据打包好,然后上传到 GPU,GPU具体渲染,这样处理可以减少GPU的压力</p>
</blockquote>
<p>但是也有限制,比如针对bitmap的 getPixel setPixel 将无法操作,对渲染绘制方面限制,高斯模糊,圆角等都会抛出异常,并且数量不能过多,每个进程都有一个FD上限(文件描述符),超过了1024会导致加载失败,而每个图片缓存都会消耗一个FD,所以需要谨慎使用</p>
<p>trace中看到,其实只是针对upload部分,但是buffer等操作不可避免,依然是在同线程处理,但也可以应付大部分场景了</p>
<p>当然,前提是在应用内,已经优化到极致,比如图片加载时使用override裁剪处理,图片对清晰度要求不高可以压缩处理等</p>
<h4>方案二</h4>
<p>多线程处理,将该部分绘制丢到子线程中操作</p>
<p><img src="https://img2024.cnblogs.com/blog/583064/202603/583064-20260330142744829-1590680644.png"></p>
<p>可以看到,渲染部分交给了单独线程中service去绘制,不过buffer部分依然实在主线程</p>
<p>通过上面验证,想要进一步优化,只能独立进程,才能彻底分离,否则只能在draw层次去优化</p>
<p> </p>
<p>场景:动效卡顿掉帧</p>
<p><img src="https://img2024.cnblogs.com/blog/583064/202603/583064-20260330151122697-1670764346.png"></p>
<p>看出一帧内绘制了五张大图,导致GPU紧张</p>
<p>动效图片是自定义上下轮播View,初始化时add了五个imageview,因为一些可定制跳转需求,recyclerview等无法满足</p>
<p>优化:针对动效动态控制显示隐藏</p>
<div class="cnblogs_code"><img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_26cbfe7b-da3e-419b-9cff-04aff0ac0ccd" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_26cbfe7b-da3e-419b-9cff-04aff0ac0ccd" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">override fun setTranslationX(translationX: Float) {
</span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.setTranslationX(translationX)
updateVisible()
}
override fun setTranslationY(translationY: Float) {
</span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.setTranslationY(translationY)
updateVisible()
}
override fun setAlpha(alpha: Float) {
</span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.setAlpha(alpha)
updateVisible()
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
</span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onLayout(changed, left, top, right, bottom)
updateVisible()
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> fun updateVisible() {
visibility </span>= <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (
translationX </span>>= measuredWidth || translationX <= -measuredWidth ||<span style="color: rgba(0, 0, 0, 1)">
translationY </span>>= measuredHeight || translationY <= -measuredHeight ||<span style="color: rgba(0, 0, 0, 1)">
alpha </span>==<span style="color: rgba(0, 0, 0, 1)"> 0f
) {
INVISIBLE
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
VISIBLE
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>动效过程中,一共只需要显示两张图片,动效结束后只需要显示一张图片,那么可以根据参数更新view状态,调整后在看新的trace</p>
<p><img alt="image" width="615" height="205" loading="lazy" src="https://img2024.cnblogs.com/blog/583064/202603/583064-20260330152750458-408730658.png"></p>
<p>除了绘制,还需要关注measure</p>
<p><img src="https://img2024.cnblogs.com/blog/583064/202603/583064-20260330153443510-1227734604.png"></p>
<p>recyclerview中加载是否耗时</p>
<p><img src="https://img2024.cnblogs.com/blog/583064/202603/583064-20260330154149527-1474056418.png"></p>
<p>如果系统资源紧张,Runnable的时间会超过16ms,并且大量线程处于Runnable的状态,或者频繁触发GC</p>
<p><img src="https://img2024.cnblogs.com/blog/583064/202603/583064-20260330155446493-1776749447.png"></p>
<p>选中时间段,查看cpu占比率</p>
<p><img src="https://img2024.cnblogs.com/blog/583064/202603/583064-20260330163734362-1140295853.png"></p>
<p> </p><br><br>
来源:https://www.cnblogs.com/LiuZhen/p/19795487
頁:
[1]