Android 性能优化之布局优化

文章目录

Android 性能优化之布局优化

绘制原理

  • CPU:负责执行应用层的measure、layout、draw等操作,将绘制的数据交给GPU处理。
  • GPU:进一步处理数据,并缓存数据。
  • 屏幕:由一个个像素点组成的,以固定的频率(16.6ms,1秒60帧)从缓冲区获取数据填充像素点。

双缓冲机制

GPU 向缓冲区写入数据的同时,屏幕也在向缓冲区读取数据,可能会导致屏幕上就会出现一部分是前一帧的画面,一部分是另一帧的画面。

因此 Android 系统使用双缓冲机制,GPU 只向Back Buffer中写入绘制数据,且 GPU 会定期交换Back BufferFrame Buffer,交换的频率也是60次/秒,这就与屏幕的刷新频率保持了同步。

GPU 向 Back Buffer 写入数据时,系统会锁定 Back Buffer,如果布局比较复杂或设备性能较差时,CPU 不能保证16.6ms内完成计算,因此到了 GPU 交换两个 Buffer 的时间点,GPU 就会发现 Back Buffer 被锁定了,会放弃这次交换,也就是掉帧。

布局加载原理

  • 解析XML文件,涉及 IO 操作。
  • 通过 createViewFromTag() 创建View,用到了反射机制。

检测耗时

常规方式

java 复制代码
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);
    }
}

AOP方式

使用第三方框架:

https://github.com/FlyJingFish/AndroidAOP

定义切面类:

java 复制代码
@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;
    }
}

获取控件加载耗时

java 复制代码
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);
    }
}

布局优化

优化思路:

  • IO 优化。
  • 反射优化。

AsyncLayoutInflater方案

AsyncLayoutInflater 是 Android 提供的一个异步加载布局的类,它允许在 UI 线程之外加载和解析 XML 布局文件,减少主线程的阻塞,从而提高应用的响应性能。

添加依赖库:

groovy 复制代码
implementation "androidx.asynclayoutinflater:asynclayoutinflater:1.0.0"

使用:

java 复制代码
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);
    }
});

缺点:

  • 兼容性一般。
  • 牺牲了易用性。

Compose方案

  • 新一代UI,声明式UI。
  • 去掉了 XML。

减少布局层级和复杂度

  • 使用 ConstraintLayout 可以实现扁平化布局,减少层级。
  • 使用 RelativeLayout 减少嵌套。
  • 嵌套的 LinearLayout 尽量少用 weight 属性,因为 weight 会重复测量。
  • 使用 merge 标签减少布局层级。
  • 使用 ViewStub 标签进行延迟加载。
  • 使用 include 标签提取复用布局。

避免过度绘制

  • 去掉多余的背景色,减少复杂 shape 的使用。
  • 避免层级叠加。
  • 自定义 View 使用 clipRect 屏蔽被遮盖 View 绘制。
相关推荐
游戏开发爱好者81 分钟前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
王码码20356 分钟前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
黑码哥22 分钟前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
亓才孓34 分钟前
[JDBC]元数据
android
独行soc1 小时前
2026年渗透测试面试题总结-17(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
金融RPA机器人丨实在智能1 小时前
Android Studio开发App项目进入AI深水区:实在智能Agent引领无代码交互革命
android·人工智能·ai·android studio
科技块儿1 小时前
利用IP查询在智慧城市交通信号系统中的应用探索
android·tcp/ip·智慧城市
独行soc1 小时前
2026年渗透测试面试题总结-18(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
王码码20352 小时前
Flutter for OpenHarmony 实战之基础组件:第二十七篇 BottomSheet — 动态底部弹窗与底部栏菜单
android·flutter·harmonyos
2501_915106322 小时前
app 上架过程,安装包准备、证书与描述文件管理、安装测试、上传
android·ios·小程序·https·uni-app·iphone·webview