Starting an Android Activity containing a MapView takes forever

When an android map activity is started it may take quite a while to be up and running. What is worse, it needs some time to load, which disrupts smooth user interaction when started from a list item, a button or an icon in your app. It may take up to seconds for the map activity to appear. We haven’t found a way to speed things up, but there is a way to achieve a much better user experience.

Our solution is to let the Activity render without the MapView first. It will start up quickly and display a message that the map is loading. Then add and initialize the MapView in a seperate thread.

We use OSMDroid. The same approach can be used for Google Maps.

Suppose you have the following layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
 
    <org.osmdroid.views.MapView
        android:id="@+id/mapview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
 
    <TextView
        android:id="@+id/status"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:background="#50000000"
        android:gravity="center"
        android:padding="16dp"
        android:textColor="#ffffffff"
        android:visibility="gone" />
 
</RelativeLayout>

Now completely remove the MapView and replace it with a container ViewGroup. We’ll use FrameLayout here. Add a string resource containing the message for the loading map.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
 
    <FrameLayout
        android:id="@+id/mapContainer"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
 
        <TextView
            android:id="@+id/loading"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="@string/loading_map" />
 
    </FrameLayout>
 
    <TextView
        android:id="@+id/status"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:background="#50000000"
        android:gravity="center"
        android:padding="16dp"
        android:textColor="#ffffffff"
        android:visibility="gone" />
 
</RelativeLayout>

In onCreate, use a delayed thread to add the MapView. We apply a delay of 100 ms. Experiment with this value. If it’s too low our approach has no effect at all. If it’s too high we unnecessarily delay our rendering.

mapContainer = (FrameLayout) findViewById(R.id.mapContainer);
 
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
 
    @Override
    public void run() {
        mMapView = new MapView(SetRouteActivity.this, 256);
        mMapView.setTileSource(TileSourceFactory.MAPNIK);
        mMapView.setBuiltInZoomControls(true);
        mMapView.setMultiTouchControls(true);
        mapController = SetRouteActivity.this.mMapView.getController();
        mMapView.setMaxZoomLevel(17);
        mapController.setZoom(15);
 
        org.osmdroid.views.MapView.LayoutParams mapParams = new org.osmdroid.views.MapView.LayoutParams(
                org.osmdroid.views.MapView.LayoutParams.MATCH_PARENT,
                org.osmdroid.views.MapView.LayoutParams.MATCH_PARENT,
                null, 0, 0, 0);
 
        mapContainer.addView(mMapView, mapParams);
 
        // Initialization of Overlays, location, etc. goes here.
 
    }
}, 100);

Note that the OSMDroid MapView constructor takes the tile size in pixels.

So the Activity starts immediately resulting in a reactive user experience. Then the MapView renders and becomes visible when it’s ready.

One thought on “Starting an Android Activity containing a MapView takes forever

Leave a Reply