Android mapview有时会崩溃(幻像nullpointerexception)

时间:2011-11-15 18:52:36

标签: android android-activity crash nullpointerexception android-mapview

我使用mapview的活动会随机崩溃。我认为所有可能的空变量都被处理,但是十分之一,它们不是。我已经附上了我的活动和错误。

public class HomeActivity extends MapActivity {

boolean pickup = false;

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

    findViewById(R.id.searchBar).setVisibility(View.VISIBLE);

    findViewById(R.id.searchBar).setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            //load new dialog thing with only a onSearchRequested() thing, and a bg click that finishes the app

            //but also somehow returns the result back to the map??? put intent, here get intent on resume()?? or whatever, debug breakpoints
            findViewById(R.id.searchBar).setVisibility(View.GONE);

            Intent pseudoSearch = new Intent(HomeGroup.group, PseudoMapSearchActivity.class);
            startActivityForResult(pseudoSearch, 0);
        }

    });

    // initialize the map and set the default location
    MapView map = (MapView) findViewById(R.id.map);
    //map.setBuiltInZoomControls(true);
    map.setSatellite(false);


    MapController controller = map.getController();
    List<Overlay> overlays = map.getOverlays();

    Drawable drawable = this.getResources().getDrawable(
            R.drawable.origin_pin);
    HomeItemizedOverlay overlay = new HomeItemizedOverlay(drawable,
            HomeGroup.group);


    overlays.clear();
    overlays.add(overlay);

    controller.setZoom(17);
    map.postInvalidate();

    final LocationManager locator = (LocationManager) this
            .getSystemService(Context.LOCATION_SERVICE);
    String provider = "";

    // check what location provider is available
    if (!locator.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        //provider = LocationManager.GPS_PROVIDER;

        //force user to turn on gps
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        criteria.setPowerRequirement(Criteria.POWER_HIGH);

        LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        provider = lm.getBestProvider(criteria, true);
    } else {
        provider = LocationManager.GPS_PROVIDER;
    }

    // get the current location
    if (provider != null) {
        //setLocation(locator.getLastKnownLocation(provider));

        final LocationListener listener = new LocationListener() {

            @Override
            public void onLocationChanged(Location location) {
                setLocation(location);
                locator.removeUpdates(this);
            }

            @Override
            public void onProviderDisabled(String provider) {
            }

            @Override
            public void onProviderEnabled(String provider) {
            }

            @Override
            public void onStatusChanged(String provider, int status,
                    Bundle extras) {
            }
        };

        locator.requestLocationUpdates(provider, 15000, 0, listener);
    } else {
        Toast toast = Toast.makeText(HomeActivity.this,
                "Location provider could not be found.", Toast.LENGTH_LONG);
        toast.show();
    }

}

/**
 * Performs any action required to update the current location displayed on
 * the home map.
 * 
 * @param location
 *            A {@link Location} object with the new location to display.
 */
private void setLocation(Location location) {

    if (location == null) {
        return;
    }

    if(AndroidHelper.pickup == false)
    {
        MapView map = (MapView) findViewById(R.id.map);
        map.setSatellite(false);

        MapController controller = map.getController();
        List<Overlay> overlays = map.getOverlays();

        Drawable drawable = this.getResources().getDrawable(
            R.drawable.origin_pin);
        HomeItemizedOverlay overlay = new HomeItemizedOverlay(drawable,
            HomeGroup.group);

        int latitude = (int) (location.getLatitude() * 1e6);
        int longitude = (int) (location.getLongitude() * 1e6);

        GeoPoint point = new GeoPoint(latitude, longitude);
        if(point!=null)
        {   
            OverlayItem item = new OverlayItem(point, "Current Location",
                    "This is where you are currently located.");
            overlay.setOrigin(item);
        }
        overlays.clear();
        overlays.add(overlay);

        controller.animateTo(point);
        controller.setZoom(18);
        map.postInvalidate();
    }



}

这是我的HomeItemizedOverlay类

 public class HomeItemizedOverlay extends ItemizedOverlay<OverlayItem> {

    private Map<Integer, OverlayItem> overlays = null;
    private Context context = null;

    private static final int ORIGIN = 0;
    private static final int DESTINATION = 1;

    public HomeItemizedOverlay(Drawable defaultMarker) {
            super(boundCenterBottom(defaultMarker));
            this.overlays = new HashMap<Integer, OverlayItem>();
    }

    public HomeItemizedOverlay(Drawable defaultMarker, Context context) {
            this(defaultMarker);
            this.context = context;
    }

    /**
     * Set an {@link OverlayItem} to be the origin and calls {@link #populate()}
     * to create the overlay.
     * 
     * @param item
     *            An item to add to the overlay.
     */
    public void setOrigin(OverlayItem item) {
            this.overlays.put(ORIGIN, item);
            populate();
    }

    /**
     * Adds an {@link OverlayItem} to be the destination and calls
     * {@link #populate()} to create the overlay.
     * 
     * @param item
     *            An item to add to the overlay.
     */
    public void setDestination(OverlayItem item) {
            this.overlays.put(DESTINATION, item);
            populate();
    }

    @Override
    protected OverlayItem createItem(int i) {
            return this.overlays.get(i);
    }

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

    @Override
    protected boolean onTap(int index) {
            OverlayItem item = this.overlays.get(index);

            //think this causes crashes
            AlertDialog.Builder dialog = new AlertDialog.Builder(this.context);
            dialog.setTitle(item.getTitle());
            dialog.setMessage(item.getSnippet());
            dialog.show();

            return true;
    }
}

这个logcat错误没有在我的代码中提到一行,所以我真的不明白它在哪里破解。这种情况大约发生在10次中。

11-15 13:47:13.192: E/AndroidRuntime(3585): FATAL EXCEPTION: main
11-15 13:47:13.192: E/AndroidRuntime(3585): java.lang.NullPointerException
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.google.android.maps.ItemizedOverlay.getItemsAtLocation(ItemizedOverlay.java:617)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.google.android.maps.ItemizedOverlay.getItemAtLocation(ItemizedOverlay.java:586)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.google.android.maps.ItemizedOverlay.handleMotionEvent(ItemizedOverlay.java:498)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.google.android.maps.ItemizedOverlay.onTouchEvent(ItemizedOverlay.java:572)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.google.android.maps.OverlayBundle.onTouchEvent(OverlayBundle.java:63)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.google.android.maps.MapView.onTouchEvent(MapView.java:679)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.view.View.dispatchTouchEvent(View.java:3882)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:903)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1691)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1125)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.app.Activity.dispatchTouchEvent(Activity.java:2096)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1675)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1691)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1125)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.app.Activity.dispatchTouchEvent(Activity.java:2096)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1675)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1691)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1125)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.app.Activity.dispatchTouchEvent(Activity.java:2096)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1675)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2204)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1888)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.os.Looper.loop(Looper.java:130)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at android.app.ActivityThread.main(ActivityThread.java:3683)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at java.lang.reflect.Method.invokeNative(Native Method)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at java.lang.reflect.Method.invoke(Method.java:507)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
11-15 13:47:13.192: E/AndroidRuntime(3585):     at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:2)

在构造函数中调用populate()后,请立即尝试调用super。还有其他类似问题的投诉http://code.google.com/p/android/issues/detail?id=2035

populate的javadoc说:

  

对新的ItemizedOverlay执行所有处理的实用程序方法。子类通过createItem(int)方法提供Items。在调用任何其他内容之前,子类应该在有数据时立即调用它。

老实说不是很有帮助,但我相信你必须在你的构造函数中调用这个方法。