Jason
Jason

Reputation: 4034

Speed up launch of activity containing mapview and extends MapviewActivity

I have an app which contains an activity which is a MapviewActivity and is mostly a mapview. However I have noticed that the start up time of the activity is really slow and causes a lag from the moment the button is pressed to go in to the map activity. I feel this creates a bad user experience and would like to avoid this. I have already set the background of the map activity to @null as suggested by one of the UI improvement articles on googles developer page, which I feel does not do the trick.

Is there a way to improve this? I would not like the main home screen to get stuck on the launch of the activity, even a transfer to the map activity and then loading the mapview would be better.

Thanks, Jason

Upvotes: 3

Views: 2552

Answers (3)

easytarget
easytarget

Reputation: 748

This has been bugging me for a while and I worked this out by expanding on on CommonsWare's answer:

I am currently using this solution that sped up my Activity loading time greatly and make everything look as smooth as it gets.

My MapActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_map); // See activity_map.xml below.

    // Start a runnable that does the entire Map setup.
    // A delay does not seem to be necessary.
    Handler mapSetupHandler = new Handler();
    Runnable mapSetupRunnable = new Runnable() {
        public void run() {
            FragmentManager fragMan = getSupportFragmentManager();
            FragmentTransaction fragTransaction = fragMan.beginTransaction();

            final SupportMapFragment mapFragment = new SupportMapFragment();
            fragTransaction.add(R.id.container_map, mapFragment, "mapFragment");
            fragTransaction.commit();

            // At the end, retrieve the GoogleMap object and the View for further setup,
            // zoom in on a region, add markers etc.
            mapFragment.getMapAsync(new OnMapReadyCallback() {
                @Override
                public void onMapReady(GoogleMap googleMap) {
                    mMap = googleMap;
                    mMapView = mapFragment.getView();
                    setUpMap();
                }
            });
        }
    };
    mapSetupHandler.post(mapSetupRunnable);
}

layout/activity_map.xml:

<RelativeLayout    
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<!--This FrameLayout will be used by the GoogleMap-->
<!--as a container for the SupportMapFragment.-->
<FrameLayout
    android:id="@+id/container_map"
    android:layout_width="match_parent"
    android:layout_height="fill_parent"
    android:layout_above="@id/bar_room_password"
    android:layout_below="@id/toolbar">

    <!--Initially the container is filled with a placeholder image.-->
    <!--A small, heavily blurred image of a map screenshot is used-->
    <!--in order to fake a loading map.-->
    <ImageView
        android:id="@+id/image_map_placeholder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:alpha="50"
        android:contentDescription="@string/map"
        android:scaleType="centerCrop"
        android:src="@drawable/placeholder_map" />
</FrameLayout>

[... more, unrelated Views...]
</RelativeLayout>

The Activity appears quickly because the setup is handled inside of a Runnable. Also, instead of just showing an empty View while the GoogleMap is doing its setup and downloads, I show a vague fake image of a map.

The Google logo is being placed on top of the ImageView relatively early so it looks pretty convincing with just a 128x128 pixel image:

ImageView below GoogleMap in an Activity as a mock loading screen

Upvotes: 2

durka42
durka42

Reputation: 1592

I tried CommonsWare's answer, but there was a significantly delay launching even a bare MapActivity without a MapView in it.

So, I put another activity in the middle, "MapLoading". My home activity launches MapLoading, which then uses post() to immediately launch the MapActivity. Because of the lag, the app sticks on MapLoading for a few seconds (which is the intended result, as opposed to sticking on my home activity).

The MapLoading activity has noHistory set so when the back button is clicked from the MapActivity it goes right through to the home screen. Future launches of the MapActivity are very fast and the MapLoading activity just flashes on the screen.

Here is the code for MapLoading (the activity with the MapView in it is called Map):

public class MapLoading extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.maploading);

        new Handler().post(new Runnable() {
            public void run()
            {
                startActivity(new Intent(MapLoading.this, Map.class));
            }
        });
    }
}

Here is its layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/maploading"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center"
        android:textSize="14pt"
        android:text="Loading map..."
        />

</RelativeLayout>

And the corresponding stanza in AndroidManifest.xml:

<activity android:label="@string/app_name"
          android:name="MapLoading"
          android:noHistory="true" />

Upvotes: 1

CommonsWare
CommonsWare

Reputation: 1007296

You could try removing the MapView from your layout. Then, in onCreate(), use post() to schedule a Runnable to add in the MapView and do your map-related initialization from Java. By using post() (or, potentially, postDelayed()) to postpone the MapView further, you should be able to render the rest of the activity first.

I haven't tried this, so YMMV. :-)

Upvotes: 8

Related Questions