【问题标题】:Disabling hardware acceleration for mapView leads to constant redraws禁用 mapView 的硬件加速会导致不断重绘
【发布时间】:2012-11-08 04:38:14
【问题描述】:

短版: 在 xml 中使用 android:hardwareAccelerated="false" 禁用硬件加速会将我的 Theme.Sherlock.Light.DarkActionBar 主题的背景颜色更改为更白的“白色”。 编辑:这曾经是主要问题。为了强调第二个问题,我改了标题。

仅对 mapView 禁用硬件加速,会导致不断重绘。

加长版:

默认情况下,AFAIK 硬件加速在 API 级别 14 及更高级别启用。 (reference)

由于我正在为 API 级别 16 构建和测试,我的硬件加速通常是开启的,所以这是我习惯看到的。主题是浅色但不是纯白色,它是浅灰色(默认)。

我在地图上绘制了一些圆形叠加层,当我放大关闭时,地图视图变得非常滞后,并且在 logcat 中出现“太大而无法渲染为纹理”的形状错误。我发现关闭硬件加速可以解决问题。

当我在 android 清单中为应用程序(或单个活动)关闭硬件加速时,我的布局的背景颜色会发生变化。它从浅灰色变为非常浅的灰色,几乎是纯白色。这是正常行为吗?

我尝试为地图视图关闭硬件加速:

if(android.os.Build.VERSION.SDK_INT>=11) {
mapView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); }

这对于消除纹理过大错误非常有效,因为地图视图不是硬件加速的,而且它还使我的应用程序的其余部分保持硬件加速。 这将是理想的解决方案。 但是,这会导致另一个问题。它使我使用此代码的叠加层的 onDraw 方法不断被调用。即,onDraw 本身被一遍又一遍地调用,而不在 mapview 上调用 invalidate()。知道为什么会这样吗?

更新:

以下是一些简单的代码,当仅为 mapView 禁用硬件加速(我想要的)时,将重新创建不断重绘的问题:

地图活动:

public class SettingsActivity extends MapActivity {

private MapView mapView;
private static List<Overlay> overlayList;
private static AccuracyCircleOverlay accuracyCircleOverlay;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_manage_maps);

    mapView = (MapView) findViewById(R.id.map);

    overlayList = mapView.getOverlays();
    accuracyCircleOverlay = new AccuracyCircleOverlay(this);
    overlayList.add(accuracyCircleOverlay);
}

@Override
protected boolean isRouteDisplayed() {
    return false;
}
}

叠加层:

public class AccuracyCircleOverlay extends Overlay {

private Context context;

public AccuracyCircleOverlay(Context context) {
    this.context = context;
}

@TargetApi(11)
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
    super.draw(canvas, mapView, shadow);

    if (android.os.Build.VERSION.SDK_INT >= 11) {
        mapView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }                 
            Log.d("accuracy OVERLAY", "being redrawn");
}
}

【问题讨论】:

  • 也遇到这个,以为只有我一个..
  • 貌似是安卓的bug,应该提交。
  • 硬件加速和你的 MapView 覆盖调用没有关系,你能发布你的 MapView 及其覆盖的源代码吗?
  • 是的,Anis,这是预期的,但不是正在发生的。更新了简化代码以显示在 mapView 上禁用硬件加速时的重绘问题。

标签: android colors background hardware acceleration


【解决方案1】:

我终于意识到问题所在了。 将mapView的图层类型设置为软件不应该从overlay的draw方法内部完成!这样做似乎会触发另一个绘图,从而导致循环。我将以下代码放在包含 mapView 的 Activity 的 onCreate 中,并且它可以正常工作。它告诉 mapView 以软件模式渲染,而不会导致不断重绘!

活动中:

if (android.os.Build.VERSION.SDK_INT >= 11) {
    mapView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}  

或者在 XML 中:

<com.google.android.maps.MapView
        ...
        android:layerType="software" />

【讨论】:

  • 真的好用!但是,我认为 Android 在这种情况下非常粗鲁。哈哈
【解决方案2】:

我很欣赏这个答案没有解决您问题的重点(我理解这是质疑为什么在关闭硬件加速时MapView 和相关的覆盖层会不断重绘 - 我承认,我真的不这样做'不知道为什么)。但是,我认为您应该打开加速,而是专注于限制您在叠加层中实际绘制的内容的大小,正如 ndw 建议的那样。

这正是我现在正在处理的应用程序中必须做的事情。我在MapView 的顶部画了一个Path,以说明来自 GPS 数据日志的路线。如果我放大得太远,Path 会突然消失,并且我会在 LOGCAT 中收到一条警告,说“形状路径太大而无法渲染成纹理”,就像你一样。我的解决方案是在地图的每次缩放上重新生成Path(考虑一下,无论如何都需要这样做,因为在每个缩放级别上,您从Projection 获得的实际像素位置显然不同) .当Path 是由您所基于的任何数据(例如GeoPoints 集)生成时,使用Projection 类来确定是否有任何路径段等远离地图并且应该是离开(这就是我对 GPS 路线所做的事情)。如果您有单个矢量对象本身可能会变得太大(例如圆圈),那么我建议您设计代码,以便如果圆圈的任何区域落在地图内,它将包括圆圈,但还包括一些逻辑如果在高缩放级别下,只需在可见区域中绘制该圆表面的一小部分(例如通过绘制正方形)。

【讨论】:

  • 是的,这正是我遇到的问题。我确实在使用投影,以便 [实心] 圆圈的大小代表真实的距离/面积。但是,圆圈​​可以动态改变大小。检查圆的所有边缘是否都在视野之外可能会很棘手,这样我就可以用单独的叠加层填充视图。你是怎么做到的?
【解决方案3】:

我不认为颜色的变化是特定于您的代码的,我也经历过同样的事情。

在没有 GPU 仿真和 holo_light 主题的情况下运行模拟器,您会得到白色背景,使用 GPU 仿真运行,您会得到浅灰色背景。

也就是说,我认为禁用硬件加速并不是解决 mapview 问题的正确方法。我会尝试找出您尝试渲染的形状太大的原因,以及是否可以采取任何措施使其变小。

【讨论】:

  • 是的,我已经意识到我想为应用程序保持硬件加速,但不介意为地图视图关闭它(这会导致第二个问题,这应该是真正的问题)。形状太大是一个常见问题,尤其是路径。在我的例子中,当你放大时,圆圈变得太大而无法渲染。如果有办法只在地图上绘制视图范围内的内容,那就行了。
  • 我也立刻想到你应该保持加速度,而是看看你是如何画圆圈的。当你说“如果有办法只在地图上绘制视图内的内容......” - 你不能简单地使用Projection(我本来以为你已经在使用它)轻松地做到这一点)确定查看区域之外的内容,因此不要将其添加到Path?我在我的应用程序中遇到了类似的问题,我正在绘制的Path 会在高缩放级别下消失。我只是避免绘制Path 的部分,这些部分超出了修复的范围。
  • 如果最大圆坐标大于您视图的最小坐标,并且最小圆坐标小于您视图的最大坐标,则您的视图中有一个圆。 (对于 X 和 Y)如果您在屏幕外绘制大量纹理,仅此一项就可以解决问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-11
  • 1970-01-01
  • 1970-01-01
  • 2011-07-02
相关资源
最近更新 更多