4

This does not refer to anywhere in my code at all. How do I go about getting to the bottom of it?

java.lang.NullPointerException
at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:42)
at com.google.android.maps.MapView.onDraw(MapView.java:494)
at android.view.View.draw(View.java:6739)
at android.view.ViewGroup.drawChild(ViewGroup.java:1648)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1375)
at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1375)
at android.view.View.draw(View.java:6742)
at android.widget.FrameLayout.draw(FrameLayout.java:352)
at android.view.ViewGroup.drawChild(ViewGroup.java:1648)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1375)
at android.view.View.draw(View.java:6742)
at android.widget.FrameLayout.draw(FrameLayout.java:352)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1872)
at android.view.ViewRoot.draw(ViewRoot.java:1422)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1167)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1744)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:144)
at android.app.ActivityThread.main(ActivityThread.java:4937)
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:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)

Here is the draw method of the ItemizedOverlay

public void draw(Canvas canvas, MapView mapView, boolean shadow) {

            try {
            super.draw(canvas, mapView, false);

            if (getMainOverlayArray().size() != 0){

            pfOverlayItem tempOver = null;
            for (int i = 0; i < getMainOverlayArray().size(); i++) {

                tempOver = getMainOverlayArray().get(i);

            boolean isMatch = false;

            if (tempOver.getTitle().equals(selectedName))
            {
                isMatch = true;
            }

            if (isMatch){

            Projection projection = mapView.getProjection();
            Point point = new Point();
            projection.toPixels(tempOver.getPoint(), point);

            Paint background = new Paint();
            background.setColor(Color.WHITE);
            background.setAlpha(150);
            RectF rect = new RectF();
            rect.set(point.x - 55, point.y +15,
                    point.x + 100, point.y + 65);
            canvas.drawRoundRect(rect, 5, 5, background);


            Paint text = new Paint();
            text.setAntiAlias(true);
            text.setColor(Color.BLUE);
            text.setTextSize(14);
            text.setTypeface(Typeface.MONOSPACE);

            canvas.drawText(tempOver.getTitle() , point.x -50 , point.y + 30, text);
            canvas.drawText(tempOver.getTypeTextOut(), point.x -50 , point.y + 45, text);
            canvas.drawText(tempOver.getdestination(), point.x -50 , point.y + 60, text);
            }
            }
            }
            }catch (Exception e){
                Log.e("Error", "Problem drawing view", e);
                e.printStackTrace();
            }
        }

I now print out the stacktrace and no difference! :-(

Does anyone have any ideas that could help get to the bottom of this?

EDIT - Latest code 28/11 FULL CLASS

    private class SitesOverlay extends ItemizedOverlay<pfOverlayItem> {
        private List<pfOverlayItem> items = new ArrayList<pfOverlayItem>();

        private PopupPanel panel=new PopupPanel(R.layout.popup);
        private MapLocation selectedMapLocation;  
        private static final int CIRCLERADIUS = 2;
        private ArrayList<pfOverlayItem> mOverlays = new ArrayList<pfOverlayItem>();



        public SitesOverlay() {

            super(null);
            //super(boundCenter(defaultMarker));
            //items = getMainOverlayArray();
            //items = mOverlays;
            populate();

        }



public void finishedLoading(){

    populate();

}

        @Override
        protected pfOverlayItem createItem(int i) {
            // Log.i("CREATE","MARKER");
            return (items.get(i));

        }

        public void addItem(OverlayItem overlay) {
            overlay.setMarker(boundCenter(overlay.getMarker(0)));
            items.add((pfOverlayItem) overlay);
            //populate();
        }

        public void clearItems(){
            runOnUiThread(new Runnable() {
                public void run() {
                    items.clear();
                    myMapView.invalidate();
                }
            });


        }

        public void clear() {
            mOverlays.clear();
            myMapView.removeAllViews();
            //numItems = 0;
            // Workaround for another bug with this class:
            // http://groups.google.com/group/android-developers/browse_thread/thread/38b11314e34714c3
            setLastFocusedIndex(-1);
            populate();
        }

        @Override
        public void draw(Canvas canvas, MapView mapView, boolean shadow) {
            super.draw(canvas, mapView, false);

            try {


            if (getMainOverlayArray().size() != 0){

            pfOverlayItem tempOver = null;
            for (int i = 0; i < getMainOverlayArray().size(); i++) {

                tempOver = getMainOverlayArray().get(i);

            boolean isMatch = false;

            //Log.i("Selected Name",selectedName);

            if (tempOver.getTitle().equals(selectedName))
            {
                isMatch = true;
            }

            if (isMatch){

            Projection projection = mapView.getProjection();
            Point point = new Point();
            projection.toPixels(tempOver.getPoint(), point);

            Paint background = new Paint();
            background.setColor(Color.WHITE);
            background.setAlpha(150);
            RectF rect = new RectF();
            rect.set(point.x - 50, point.y +15,
                    point.x + 90, point.y + 50);
            canvas.drawRoundRect(rect, 5, 5, background);


            Paint text = new Paint();
            text.setAntiAlias(true);
            text.setColor(Color.BLUE);
            text.setTextSize(14);
            text.setTypeface(Typeface.MONOSPACE);

            //canvas.drawRoundRect(rect, 2, 2, background);
            canvas.drawText(tempOver.getTitle() + " " + tempOver.getcallsign(), point.x -50 , point.y + 30, text);
            canvas.drawText(tempOver.getdestination() + " " + tempOver.getdraft(), point.x -50 , point.y + 45, text);
            }
            }
            }
            }catch (Exception e){
                Log.e("Error", "Problem drawing view", e);
                 e.printStackTrace();

            }
        }

        @Override
        protected boolean onTap(int i) {

            pfOverlayItem item = getItem(i);

            if (selectedName.equals(item.getTitle())){

                //Toast.makeText(PlaneFinderMain.this, "SECOND MOFO PRESS", 3000).show();
                try{    
                Intent myIntent = new Intent(PlaneFinderMain.this, DetailActivity.class);
                myIntent.putExtra( "int", i);
                myIntent.putExtra( "string", selectedName );
                PlaneFinderMain.this.startActivity(myIntent);
                }catch (Exception e){
                    Log.e("Error", "Cannot launch", e);
                }
            }

            currentadshex = item.getmmsi();
            new GetRouteTask(item.getmmsi()).execute();

            selectedItem = i;
            selectedName = item.getTitle();
            selectedPlanePoint = item.getPoint();

            GeoPoint geo=item.getPoint();
            Point pt=myMapView.getProjection().toPixels(geo, null);

            View view=panel.getView();

            ((TextView)view.findViewById(R.id.reg)).setText(item.getTitle());
            ((TextView)view.findViewById(R.id.flightno)).setText(item.getcallsign());
            ((TextView)view.findViewById(R.id.route)).setText(item.getdestination());
            ((TextView)view.findViewById(R.id.height)).setText(item.getdraft());

            return (true);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event, MapView mapView) {

             if (event.getAction() == MotionEvent.ACTION_DOWN){

                 if (selectedPlanePoint != null){
                     Projection projection = mapView.getProjection();
                     Point point = new Point();
                     projection.toPixels(selectedPlanePoint, point);

                     Point pointHit = new Point();
                     pointHit.x=(int)event.getX();
                     pointHit.y=(int)event.getY();

                     if ((point.x - pointHit.x) >-100 && (point.x - pointHit.x) <70  && (point.y - pointHit.y) < -25  && (point.y - pointHit.y) > -95){

                            try{    
                                 Intent myIntent = new Intent(PlaneFinderMain.this, DetailActivity.class);

                                    myIntent.putExtra( "int", selectedItem);
                                    myIntent.putExtra( "string", selectedName );
                                    PlaneFinderMain.this.startActivity(myIntent);

                                }catch (Exception e){
                                    Log.e("Error", "Cannot launch", e);
                                }

                     }else{

                     }


                 }


             }



            return false;


        }



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

        public void addOverlay(OverlayItem o){
            setLastFocusedIndex(-1);
            populate();
        }



    }
Lee Armstrong
  • 11,420
  • 15
  • 74
  • 122
  • 3
    Looks like you're passing null to an API parameter, particularly a null Overlay somewhere in a mapview probably. How are we supposed to know? – Falmarri Nov 15 '10 at 17:22
  • look at your call to OverlayBundle.draw() - that's the best we'll be able to do (a more detailed stacktrace will help) – KevinDTimm Nov 15 '10 at 17:29
  • Not a more detailed stacktrace will help but some code to find out whats null and why. – Octavian Helm Nov 15 '10 at 17:55
  • Is there a good way to enable better debugging then in Eclipse as that is all I get off the Google console. Doesn't really give much in the way of hints! – Lee Armstrong Nov 15 '10 at 18:13
  • 1
    The up call to the overridden method (`super.draw(canvas, mapView, false)`) should not be in the try block. I don't say that this is the solution but just a hint. – Octavian Helm Nov 27 '10 at 11:14
  • OK, my latest version (EDIT above) no longer has this and problem is still there :-( – Lee Armstrong Nov 28 '10 at 15:45
  • 1) When does this error occur? As soon as you add the overlay to the MapView? As soon as you populate the overlay? Or sometime later? 2) What device(s) are you testing on and what version of the SDK are they running? And what version are you building against? – Neil Traft Nov 28 '10 at 21:23
  • Unfortunately I cannot replicate on any of my test devices, (1.6>2.2!). This is just from the Console in the Google MArket – Lee Armstrong Nov 29 '10 at 08:33
  • 1
    Ohhh, ouch. In that case it may well be a device-specific bug. I've had those before, and they're a pain. Even though the Maps Add-On is a closed source Google project, the OEMs can still screw things up. For example, one version of the Droid X firmware had a bug with the MyLocationOverlay because they forgot to include a drawable resource in the build. And because it's closed source, I'm not aware of any good way to figure out what's going on. – Neil Traft Nov 29 '10 at 13:05
  • Thanks Neil, I just had an idea for your issue. Maybe you can replicate using the SDK addon? http://developer.motorola.com/docstools/tools/ – Lee Armstrong Nov 29 '10 at 13:48
  • This problem may be slightly more complicated than the code listed. The user may have generated an onPause event right after a tap/touch event. If you could repro, the solution would be trivial, I would focus on trying to repro or getting more details on how to repro. – Error 454 Nov 29 '10 at 21:06
  • Agree w/ Error 454, also it would help you to look at the Market reports and find out all the models where this is happened, so you know if it's device specific. If not, then it may be a race condition like 454 describes. – Neil Traft Dec 01 '10 at 13:42

2 Answers2

5

Actually the problem is not in the implementation of your ItemizedOverlay, but in the implementation of your MapActivity. As you can see from a similar stack trace here at line 42 the OverlayBundle is calling the draw() method of an Overlay. This points to a null Overlay that you added to your mapView somewhere.

Some helpful hints: You should definitely pass a drawable to your super constructor (used of hit-testing) by uncommenting the first line of code you already have in there:

     public SitesOverlay() {

        //super(null);
        super(boundCenter(defaultMarker));
        //items = getMainOverlayArray();
        //items = mOverlays;
        populate();

    }

and potentially not call super.draw() in your draw() method.

    @Override
    public void draw(Canvas canvas, MapView mapView, boolean shadow) {
        // why do you do this if you paint it yourself later on.
        super.draw(canvas, mapView, false

Most likely you will have to actually do both.

Edit: Come to think of it you should definitely pass a drawable to your super constructor as it is used for hit-testing. Amended the text above to reflect that.

Community
  • 1
  • 1
Gesh
  • 433
  • 3
  • 9
  • I tried passing `null` for the default marker in a test app; it yields a different error. I also tried returning a null overlay; again, different error. I was unable to produce his stack trace. But still, good advice. Also, he's not drawing the overlays himself; he's merely drawing text labels next to each overlay. However, he should not be passing `false` into `super.draw`. Lee, if you don't want shadows on your markers, you should NOT call super when `shadow == false`. – Neil Traft Dec 01 '10 at 13:25
  • Thanks guys, I thi k this is very useful stuff and I will implement but only time will tell! – Lee Armstrong Dec 01 '10 at 14:24
1
 pfOverlayItem tempOver = null;
            for (int i = 0; i < getMainOverlayArray().size(); i++) {

                tempOver = getMainOverlayArray().get(i);
boolean isMatch = false;

            if (tempOver.getTitle().equals(selectedName))
            {
                isMatch = true;
            }

Is tempOver not getting assigned?

canvas.drawText(tempOver.getTitle() , point.x -50 , point.y + 30, text);
            canvas.drawText(tempOver.getTypeTextOut(), point.x -50 , point.y + 45, text);
            canvas.drawText(tempOver.getdestination(), point.x -50 , point.y + 60, text);

is tempOver.getTitle(), .getTypeTextOut(), or .getdestination() null?

Falmarri
  • 47,727
  • 41
  • 151
  • 191
  • Surely the try would catch this though? – Lee Armstrong Nov 15 '10 at 22:40
  • Hmm. That's the problem right there. You're masking problems by doing a try/except for everything. Don't do that. Keep your try scopes as small as possible. You're not even printing a stacktrace in your except. – Falmarri Nov 16 '10 at 02:19
  • I log the error out. If I log out the e.printStackTrace(); will that give me the info I need back to the Google console to help track this down? – Lee Armstrong Nov 16 '10 at 05:18
  • After some extra help, made a comment. Now printing stackTrace and same error? – Lee Armstrong Nov 24 '10 at 15:01