Android中的硬件加速

本文介绍了Android从3.0版本开始支持的2D渲染管线硬件加速功能,并详细解释了如何在不同层级(应用、活动、窗口和视图)启用或禁用此功能。此外,还探讨了硬件加速的工作原理及对绘图操作的影响。

本文的主要内容来自SDK文章的"Hardware Acceleration”.

从Android 3.0开始,Android的2D渲染管线可以更好的支持硬件加速。硬件加速使用GPU进行View上的绘制操作。

硬件加速可以在一下四个级别开启或关闭:

  • Application
  • Activity
  • Window
  • View

Application级别

往您的应用程序AndroidManifest.xml文件为application标签添加如下的属性即可为整个应用程序开启硬件加速:

<application android:hardwareAccelerated="true" ...>

Activity级别

您还可以控制每个activity是否开启硬件加速,只需在activity元素中添加android:hardwareAccelerated属性即可办到。比如下面的例子,在application级别开启硬件加速,但在某个activity上关闭硬件加速。

<application android:hardwareAccelerated="true">
    <activity ... />
    <activity android:hardwareAccelerated="false" />
</application>

Window级别

如果您需要更小粒度的控制,可以使用如下代码开启某个window的硬件加速:

getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

注:目前还不能在window级别关闭硬件加速。

View级别

您可以在运行时用以下的代码关闭单个view的硬件加速:

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

注:您不能在view级别开启硬件加速

为什么需要这么多级别的控制?

很明显,硬件加速能够带来性能提升,android为什么要弄出这么多级别的控制,而不是默认就是全部硬件加速呢?原因是并非所有的2D绘图操作支持硬件加速,如果您的程序中使用了自定义视图或者绘图调用,程序可能会工作不正常。如果您的程序中只是用了标准的视图和Drawable,放心大胆的开启硬件加速吧!具体是哪些绘图操作不支持硬件加速呢?以下是已知不支持硬件加速的绘图操作:

Android的绘制模型

开启硬件加速后,Android框架将采用新的绘制模型。基于软件的绘制模型和基于硬件的绘制模型有和不同呢?

基于软件的绘制模型

在软件绘制模型下,视图按照如下两个步骤绘制:

1. Invalidate the hierarchy(注:hierarchy怎么翻译?)

2. Draw the hierarchy

应用程序调用invalidate()更新UI的某一部分,失效(invalidation)消息将会在整个视图层中传递,计算每个需要重绘的区域(即脏区域)。然后Android系统将会重绘所有和脏区域有交集的view。很明显,这种绘图模式存在缺点:

1. 每个绘制操作中会执行不必要的代码。比如如果应用程序调用invalidate()重绘button,而button又位于另一个view之上,即使该view没有变化,也会进行重绘。

2. 可能会掩盖一些应用程序的bug。因为android系统会重绘与脏区域有交集的view,所以view的内容可能会在没有调用invalidate()的情况下重绘。这可能会导致一个view依赖于其它view的失效才得到正确的行为。

基于硬件的绘制模型

Android系统仍然使用invalidate()和draw()来绘制view,但在处理绘制上有所不同。Android系统记录绘制命令到显示列表,而不是立即执行绘制命令。另一个优化就是Android系统只需记录和更新标记为脏(通过invalidate())的view。新的绘制模型包含三个步骤:

1. Invalidate the hierarchy

2. 记录和更新显示列表

3. 绘制显示列表

Android 中,硬件加速直观上是依赖 GPU 实现图形绘制加速,其核心是将图形绘制工作从 CPU 转移至 GPU 处理。与普通软件绘制同,硬件加速仅在绘制方面有优化,在绘制前构建绘制区域上也有很大改进。 从绘制的计算工作角度来看,硬件加速View 中绘制的计算工作,即把绘制方法中的那些 `Canvas.drawXXX()` 变成实际像素的工作交给 GPU 处理 [^2]。这样做减轻了 CPU 的压力,同时由于 GPU 擅长并行处理图形计算,使得计算速度加快 [^3]。 在关键技术支撑方面,有以下几点: - **OpenGL ES**:提供跨平台图形 API,实现 GPU 指令标准化,可处理贝塞尔曲线、纹理混合等操作 [^5]。 - **RenderThread**:作为独立渲染线程,分离了 UI 线程与 GPU 任务,有助于提升动画的流畅性 [^5]。 - **图层合成**:合并多个 RenderNode 输出,减少重绘区域,可实现窗口平移、旋转等特效 [^5]。 性能对比上,与软件绘制相比,硬件加速的图形计算主体是 GPU(并行处理),而软件绘制是 CPU(串行处理);硬件加速内存消耗低,可复用 DisplayList 和离屏缓冲,软件绘制则频繁生成 Bitmap,内存消耗高;硬件加速动画流畅度能达到 60 FPS 以上,依赖 VSync 同步,软件绘制易卡顿,因为 CPU 负载高 [^5]。 在内存管理上,硬件加速分配帧缓冲区(Frame Buffer),使其直接与显示硬件交互,减少了 CPU 与 GPU 间的数据拷贝 [^5]。 在典型应用优化方面,例如圆角/阴影效果可通过 GPU 着色器(Shader)实现,避免 CPU 生成 Bitmap;复杂动画使用硬件加速的属性动画(如 translationX),可跳过视图重排;列表滚动采用 RenderThread 异步渲染,减少主线程阻塞 [^5]。 ### 代码示例 以下是一个简单的 Android 代码示例,展示硬件加速在动画中的应用: ```java import android.animation.ObjectAnimator; import android.os.Bundle; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView = findViewById(R.id.textView); // 使用硬件加速的属性动画 ObjectAnimator animator = ObjectAnimator.ofFloat(textView, "translationX", 0f, 200f); animator.setDuration(1000); animator.start(); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值