我在谷歌播放中得到了非常奇怪的崩溃报告。测试时我没有任何错误,但我的用户有。将CustomLocationProvider设置为Google Map mMap.setLocationSource(customLocationProvider);
时,会抛出NullPointerException。什么可能是错的?
FragmentMap.java:
@Override
public void onResume(){
super.onResume();
setUpMapIfNeeded();
}
@Override
public void onPause(){
super.onPause();
customLocationProvider.deactivate();
}
@Override
public void onDestroy(){
super.onDestroy();
customLocationProvider.deactivate();
}
/**
* Set Up map if it was not already created.
*/
private void setUpMapIfNeeded() {
if (mMap == null) {
mMap = ((SupportMapFragment) getChildFragmentManager()
.findFragmentById(R.id.map))
.getMap();
if (mMap != null) {
setUpMap();
}
}
customLocationProvider = new CustomLocationProvider(getActivity());
mMap.setLocationSource(customLocationProvider);
}
/**
* Set Up map parameters.
*/
private void setUpMap() {
mMap.setOnMapClickListener(MapClick.freeModeClick);
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.setOnMarkerClickListener(MapClick.markerClickListener);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.setMyLocationEnabled(true);
}
CustomLocationProvider.java:
public class CustomLocationProvider implements LocationSource, LocationListener
{
private OnLocationChangedListener listener;
private LocationManager locationManager;
public CustomLocationProvider(Context context){
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
}
@Override
public void activate(OnLocationChangedListener listener){
this.listener = listener;
LocationProvider gpsProvider = locationManager.getProvider(LocationManager.GPS_PROVIDER);
if(gpsProvider != null) {
locationManager.requestLocationUpdates(gpsProvider.getName(), 500, 5, this);
}
LocationProvider networkProvider = locationManager.getProvider(LocationManager.NETWORK_PROVIDER);
if(networkProvider != null) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000 * 60 * 3, 0, this);
}
}
@Override
public void deactivate(){
locationManager.removeUpdates(this);
}
@Override
public void onLocationChanged(Location location){
/* Push location updates to the registered listener..
(this ensures that my-location layer will set the blue dot at the new/received location) */
if(listener != null && location != null){
listener.onLocationChanged(location);
}
}
@Override
public void onProviderDisabled(String provider)
{
}
@Override
public void onProviderEnabled(String provider)
{
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
// TODO Auto-generated method stub
}
}
崩溃报告:
ComponentInfo{lt.noframe.fieldsareameasure/lt.noframe.fieldsareameasure.views.ActivityDrawer}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2382)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2434)
at android.app.ActivityThread.access$600(ActivityThread.java:162)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5431)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at app.views.FragmentMap.setUpMapIfNeeded(FragmentMap.java:209)
at app.views.FragmentMap.onCreateView(FragmentMap.java:97)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1786)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1489)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:548)
at lt.noframe.fieldsareameasure.views.ActivityDrawer.onStart(ActivityDrawer.java:68)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1170)
at android.app.Activity.performStart(Activity.java:5132)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2355)
答案 0 :(得分:1)
对setUpMapIfNeeded()
的简单回顾表明,拥有NPE肯定不是不可能的。请参阅我在方法中添加的评论:
private void setUpMapIfNeeded() {
if (mMap == null) {
//here if mMap is null, you are trying to get a reference to it
mMap = ((SupportMapFragment) getChildFragmentManager()
.findFragmentById(R.id.map))
.getMap();
//you are checking if the reference that was returned is null
//this means (at least to me) that you are suspecting
//mMap could be null at this point
if (mMap != null) {
setUpMap();
}
}
customLocationProvider = new CustomLocationProvider(getActivity());
//if getMap() returned null, here you will have NPE
mMap.setLocationSource(customLocationProvider);
}
检查文档here,结果证明此方法可以返回null,甚至已弃用。
解决方案应如文档所述:
“改为使用getMapAsync(OnMapReadyCallback)。回调方法为您提供了一个保证非空并且可以使用的GoogleMap实例。”