查阅资料,会发现 Android 4.0开始则默认开启硬件加速;
另外再查阅资料,还会发现:
在Android中,可以四给不同层次上开启硬件加速:
1、Application
<applicationandroid:hardwareAccelerated="true">
2、Activity
<activityandroid:hardwareAccelerated="true">
3、Window
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
4、View
view.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
那么问题来了:
- 官方声明 4.0 后默认开启硬件加速指的是application全局hardwareAccelerated="true"吗?
- 如果1 不是,那么默认开启硬件加速指的是什么?与hardwareAccelerated="true"有什么区别?
- 如果不手动设置hardwareAccelerated,默认读取到的view LayerType是哪个?是否算是开了硬件加速?
更多问答 >>
-
每日一问 | Android 模块化依赖中的资源冲突该如何规避?
2023-05-24 17:30 -
每日一问 | targetSdkVersion 有什么神奇的魔力?
2023-05-24 17:30 -
每日一问 | Java线程栈的栈溢出(StackOverflowError)是如何检测的?
2024-02-19 18:30 -
2024-06-17 09:16
-
2024-06-06 11:06
-
每日一问 | 瘦身属性?对android:extractNativeLibs属性的探讨
2022-12-07 14:43 -
每日一问 | App在运行状态,可以动态安装apk,并且不重新启动吗?
2022-11-20 12:46 -
2022-11-08 21:50
-
2022-11-08 21:50
-
大家提问 Android中前后台切换监听,如果涉及到多进程如何完美的解决?
2022-12-04 22:50
Q1.:官方声明 4.0 后默认开启硬件加速指的是application全局hardwareAccelerated="true"吗?
A1:是的,在PMS会收集各APP的信息时,在PackageParser.parseBaseApplication会传入各APP的AndroidManifest.xml文件解析,其中包括
<applicationandroid:hardwareAccelerated="true">
,default值就是targetSdkVersion >= Android 4.0。并且根据上面的解析代码能知道
我们可以通过两种方式得知是否开启了全局硬件加速Q2: 如果1 不是,那么默认开启硬件加速指的是什么?与hardwareAccelerated="true"有什么区别?
A2: Q1得知,默认开启硬件加速和显式指定hardwareAccelerated="true"是一致的。
Q3:如果不手动设置hardwareAccelerated,默认读取到的view LayerType是哪个?是否算是开了硬件加速?
A3: 如果没有对View手动调用view.setLayerType设置的话,那么View的LayerType则一直是默认值LAYER_TYPE_NONE(int 类型,值为0),通过这个值是无法判断当前View是否开了硬件加速。
接下来我们分析下通过View.LayerType为什么无法判断是否开启了硬件加速。
在Application或者Activity或者Window上开启硬件加速,最终都会作用到WindowManager.LayoutParams上
WindowManager.LayoutParams |= FLAG_HARDWARE_ACCELERATED,这个参数会作用到ViewRootImpl.enableHardwareAcceleration(WindowManager.LayoutParams attrs)
上。(PS:这里注意一点,通过以上三种方式一旦开启后,都是无法关闭硬件加速的,此时就只能使用view.setLayerType(View.LAYERTYPESOFTWARE,null)的方式来单独关闭。)
我们来分析下
ViewRootImpl.enableHardwareAcceleration
ViewRootImpl.enableHardwareAcceleration
发生在ViewRoomImpl初始化过程中,用来确认是否使用硬件加速。这里关键是mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(xxx)
当你使用硬件加速时,RootViewImpl会使用mAttachInfo.mThreadedRenderer.draw()来绘制view树。
没有使用硬件加速时,RootViewImpl.drawSoftware()也就走了正常的draw逻辑。当使用硬件加速时,绘制路径为updateDisplayListIfDirty - dispatchGetDisplayList - recreateChildDisplayList递归绘制,而如果在updateDisplayListIfDirty过程中,发现当前view的layerType被置为了LAYER_TYPE_SOFTWARE,那么对于该view及其子View都使用软件绘制。
如何判断当前View是硬件加速绘制还是软件绘制?
我没找到很好的方式,因为如果当前Window指定了硬件加速,其中一个View指定了软件绘制,那么该View下的子View全部会走软件绘制,而此时子View的layerType = 0,且我没有找到其他能标志该子View是被软件绘制出来的信息。
我想到的办法是从子View开始遍历到根View,如果遍历过程所有View的layerType均没有被设置为LAYER_TYPE_SOFTWARE,且View.isHardwareAccelerated()为true,那么则判断为硬件加速绘制,否则为软件绘制。
Google提供了Canvas.isHardwareAccelerated()来判断当前画布是否硬件加速 https://developer.android.com/topic/performanc ...查看更多
Google提供了Canvas.isHardwareAccelerated()来判断当前画布是否硬件加速 https://developer.android.com/topic/performance/hardware-accel#determining
是的,可以通过这种方式得知,这种方式需要你能获取到view的canvas,你有办法在外部获取到该view的canvas吗
楼主写的真好,佩服!!!前段时间看扔老师的视频课程中讲到的硬件加速,都没楼主讲的透彻!
在 Android 系统的开发者选项中,有一个名为“停用HW叠加层”(Disable HW overlays)的选项,如何指定某个应用或者某个 SurfaceView单独启用这个功能而不影响整个系统的 ...查看更多
在 Android 系统的开发者选项中,有一个名为“停用HW叠加层”(Disable HW overlays)的选项,如何指定某个应用或者某个 SurfaceView单独启用这个功能而不影响整个系统的设置,重金悬赏!