Disabling hardware acceleration for mapView leads to constant redraws

爱⌒轻易说出口 提交于 2021-02-19 01:17:22

问题


Short version: Disabling hardware acceleration with android:hardwareAccelerated="false" in xml changes the background color of my Theme.Sherlock.Light.DarkActionBar theme to a whiter "white". EDIT: this used to be the main question. I changed the title to emphasize the second problem.

Disabling hardware acceleration for the mapView only, causes constant redraws.

Long version:

AFAIK hardware acceleration is enabled by default on API level 14 and up. (reference)

Since I'm building and testing for API level 16, my hardware acceleration was usually on so that's what I was used to seeing. The theme is light but not quite pure white, it's a light grey (default).

I had some circle overlays being drawn on a map and when I zoomed in close, the mapview was becoming very laggy and I was getting a shape "too large to be rendered into a texture" error in logcat. I discovered that turning hardware acceleration off fixes the problem.

When I turn hardware acceleration off for the application (or an individual activity) in the android manifest, the background color of my layouts changes. It goes from a light grey to a very very light grey, almost pure white. Is this normal behavior?

I tried turning off hardware acceleration just for the mapview with:

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

This works great to get rid of the texture too large errors because the mapview is not hardware accelerated AND it also keeps the rest of my app hardware accelerated. This would be the ideal solution. However, this causes another problem. It makes the onDraw method of the overlays where I use this code get called constantly. i.e, onDraw is called over and over and over by itself without calling invalidate() on the mapview. Any idea why this would be the case?

UPDATE:

Below is some simple code that will recreate the issue with the constant redraws when hardware acceleration is disabled only for the mapView (what I want):

MapActivity:

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;
}
}

Overlay:

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");
}
}

回答1:


I finally realized what the problem was. Setting the layer type of the mapView to software should not be done from inside the draw method of the overlay! Doing that seems to trigger another draw, hence causing a loop. I put the following code in the onCreate of my Activity that holds the mapView and it worked. It tells the mapView to render in software mode without causing constant redraws!

In activity:

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

Or alternatively in XML:

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



回答2:


I appreciate that this answer doesn't address the focus of your question (which I understand to be questioning why the MapView and associated overlays constantly redraw when hardware acceleration is turned off - which, I admit, I really don't know why). However, I think you should leave the acceleration turned on and instead focus on restricting the size of what you're actually drawing in the overlay, as ndw suggests.

This is exactly what I have had to do in the application I'm working on right now. I am drawing a Path over the top of my MapView to illustrate a route from a log of GPS data. If I zoom in too far, the Path suddenly disappears, and I get a warning in LOGCAT saying "Shape path too large to be rendered into a texture", just as you have. My solution to fix it is to regenerate the Path on each zoom of the map (which, thinking about it, needs to be done anyway because on each zoom level, the actual pixel positions you get from Projection are obviously different). When the Path is generated by whatever data you're basing it on (e.g. set of GeoPoints) use the Projection class to determine if any path segments, etc. are way, way off the map and should be left off (which is what I am doing with my GPS route). If you have single vector objects which by themselves can get too large (such as a circle), then I suggest you design the code so that it will include the circle if any of its area falls within the map, but also include some logic to just draw a small portion of that circle's surface (e.g. by drawing a square) in the visible region if at a high zoom level.




回答3:


I don't think the change is color is specific to your code, I've experienced the same thing.

Run the emulator without GPU emulation and holo_light theme and you get a white background, run with GPU emulation and you get the light gray background.

That said, I don't think disabling hardware acceleration is the right solution to your mapview problem. I would try to find out why the shape you're trying to render is too large and if there's anything you can do to make it smaller.



来源:https://stackoverflow.com/questions/13467664/disabling-hardware-acceleration-for-mapview-leads-to-constant-redraws

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!