赞
踩
GPU 向缓冲区写入数据的同时,屏幕也在向缓冲区读取数据,可能会导致屏幕上就会出现一部分是前一帧的画面,一部分是另一帧的画面。
因此 Android 系统使用双缓冲机制,GPU 只向Back Buffer
中写入绘制数据,且 GPU 会定期交换Back Buffer
和Frame Buffer
,交换的频率也是60次/秒,这就与屏幕的刷新频率保持了同步。
GPU 向 Back Buffer 写入数据时,系统会锁定 Back Buffer,如果布局比较复杂或设备性能较差时,CPU 不能保证16.6ms内完成计算,因此到了 GPU 交换两个 Buffer 的时间点,GPU 就会发现 Back Buffer 被锁定了,会放弃这次交换,也就是掉帧。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
long start = System.currentTimeMillis();
setContentView(R.layout.activity_main);
long time = System.currentTimeMillis() - start;
Log.e("TAG", "setContentView耗时:" + time);
}
}
使用第三方框架:
https://github.com/FlyJingFish/AndroidAOP
定义切面类:
@AndroidAopMatchClassMethod( targetClassName = "androidx.appcompat.app.AppCompatActivity", methodName = {"setContentView"}, type = MatchType.SELF ) public class MatchSetContentView implements MatchClassMethod { @Nullable @Override public Object invoke(@NonNull ProceedJoinPoint proceedJoinPoint, @NonNull String methodName) { Class<?> targetClass = proceedJoinPoint.getTargetClass(); long start = System.currentTimeMillis(); proceedJoinPoint.proceed(); long time = System.currentTimeMillis() - start; Log.e("TAG", targetClass.getSimpleName() + "#" + methodName + "耗时:" + time); return null; } }
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { LayoutInflaterCompat.setFactory2(getLayoutInflater(), new LayoutInflater.Factory2() { @Nullable @Override public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) { long start = System.nanoTime(); View view = getDelegate().createView(parent, name, context, attrs); Log.e("TAG", name + "耗时:" + (System.nanoTime() - start) + "ns"); return view; } @Nullable @Override public View onCreateView(@NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) { return null; } }); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
优化思路:
AsyncLayoutInflater 是 Android 提供的一个异步加载布局的类,它允许在 UI 线程之外加载和解析 XML 布局文件,减少主线程的阻塞,从而提高应用的响应性能。
添加依赖库:
implementation "androidx.asynclayoutinflater:asynclayoutinflater:1.0.0"
使用:
new AsyncLayoutInflater(this).inflate(R.layout.activity_main, null, new AsyncLayoutInflater.OnInflateFinishedListener() {
@Override
public void onInflateFinished(@NonNull View view, int resid, @Nullable ViewGroup parent) {
setContentView(view);
}
});
缺点:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。