Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disabling hardware acceleration for mapView leads to constant redraws

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");
}
}
like image 540
Flyview Avatar asked Nov 20 '12 06:11

Flyview


1 Answers

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" />
like image 117
Flyview Avatar answered Sep 23 '22 05:09

Flyview