NullPointerException in ItemizedOverlay.getIndexToDraw

I have a relatively simple MapActivity that I'm trying to make display a list of "camps" within a given map region. I've created a custom subclass of OverlayItem called CampOverlayItem, a custom ItemizedOverlay called CampsOverlay that returns CampOverlayItems, and of course a MapActivity subclass that populates the map.

I'm pulling the overlay data from a database using an AsyncTask as created in my activity. The AsyncTask is triggered from a ViewTreeObserver.OnGlobalLayoutListener attached to the MapView.

In the onPostExecute method of the AsyncTask, I create a new instance of my CampsOverlay class and pass it a list of the camps returned from the database (which are fetched in doInBackground). I then call:

mapView.getOverlays().add(newOverlay);

where newOverlay is the CampsOverlay I just created. All of this code runs without error, but when the Map tries to draw itself, I get a NullPointerException with the following stack trace:

java.lang.NullPointerException
   at
com.google.android.maps.ItemizedOverlay.getIndexToDraw(ItemizedOverlay.java:
211)
   at
com.google.android.maps.ItemizedOverlay.draw(ItemizedOverlay.java:240)
   at com.google.android.maps.Overlay.draw(Overlay.java:179)
   at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:
42)
   at com.google.android.maps.MapView.onDraw(MapView.java:476)
   at android.view.View.draw(View.java:6274)
   at android.view.ViewGroup.drawChild(ViewGroup.java:1526)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
   at android.view.ViewGroup.drawChild(ViewGroup.java:1524)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
   at android.view.View.draw(View.java:6277)
   at android.widget.FrameLayout.draw(FrameLayout.java:352)
   at android.view.ViewGroup.drawChild(ViewGroup.java:1526)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
   at android.view.ViewGroup.drawChild(ViewGroup.java:1524)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
   at android.view.ViewGroup.drawChild(ViewGroup.java:1524)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
   at android.view.ViewGroup.drawChild(ViewGroup.java:1524)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
   at android.view.ViewGroup.drawChild(ViewGroup.java:1524)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
   at android.view.View.draw(View.java:6277)
   at android.widget.FrameLayout.draw(FrameLayout.java:352)
   at android.view.ViewGroup.drawChild(ViewGroup.java:1526)
   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
   at android.view.View.draw(View.java:6277)
   at android.widget.FrameLayout.draw(FrameLayout.java:352)
   at com.android.internal.policy.impl.PhoneWindow
$DecorView.draw(PhoneWindow.java:1883)
   at android.view.ViewRoot.draw(ViewRoot.java:1332)
   at android.view.ViewRoot.performTraversals(ViewRoot.java:1097)
   at android.view.ViewRoot.handleMessage(ViewRoot.java:1613)
   at android.os.Handler.dispatchMessage(Handler.java:99)
   at android.os.Looper.loop(Looper.java:123)
   at android.app.ActivityThread.main(ActivityThread.java:4203)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:521)
   at com.android.internal.os.ZygoteInit
$MethodAndArgsCaller.run(ZygoteInit.java:791)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
   at dalvik.system.NativeStart.main(Native Method)

Because it seems particularly relevant, here is the code for my ItemizedOverlay subclass:

public class CampsOverlay extends ItemizedOverlay<CampOverlayItem> {
    private ArrayList<Camp> camps = null;

    public CampsOverlay(Drawable defaultMarker, ArrayList<Camp> theCamps)
{
        super(defaultMarker);
        this.camps = theCamps;
    }

    @Override
    protected CampOverlayItem createItem(int i) {
        Camp camp = camps.get(i);
        CampOverlayItem item = new CampOverlayItem(camp);
        return item;
    }

    @Override
    protected boolean onTap(int index) {
        // TODO Auto-generated method stub
        return super.onTap(index);
    }

    @Override
    public int size() {
        return camps.size();
    }

}

Does anyone have any idea what could be happening here? I've attempted to verify that everything I have control over is non-null. I can provide more code if necessary.

Answers


I do not see where you are calling populate() on your CampsOverlay.

Here is a sample project showing asynchronous loading of overlay items -- perhaps it will give you some ideas, if populate() is not the issue.


He is correct. You must call populate() to populate the overlay. You may want to create all the overlay items in the constructor, call populate, and in createItem just return the item from a list.


"Now I just have to figure out why the overlay items aren't appearing"

In case you didn't, it's because you have to use a static function on your Drawable that will explain how is your marker positioned.

You can use this, in your CampsOverlay constructor:

super(boundCenter(defaultMarker));

This will indicate that the origin of your Drawable is the center. You can also use boundCenterBottom() to indicate that the origin is the bottom center of the Drawable.


Need Your Help

Using Thread with Vaadin?

java multithreading progress-bar javamail vaadin7

I'm trying to use Thread in my project to send emails. When I click on a Button, a Thread is started and a ProgressBar is displayed. As soon as all mails are sent, the ProgressBar doesn't disappear.

Adding another dimension to array

php arrays multidimensional-array

I have an array of TLDs and prices, and now I want to be able to add a classification i.e. 'Australian','New Zealand','Industry' to the domains but I am having troubles adding the extra dimension.