以编程方式创建 MapView 并添加标记导致片段中出现空指针异常

Posted

技术标签:

【中文标题】以编程方式创建 MapView 并添加标记导致片段中出现空指针异常【英文标题】:Programmatically Creating MapView and Adding a Marker Results in a null pointer exception in the fragment 【发布时间】:2017-06-05 23:19:35 【问题描述】:

我正在尝试以编程方式创建 MapView 并添加 MarkerPosition,如下所示:

MapView mapView = new MapView(getActivity());
((ViewGroup) rootView).addView(mapView);

GoogleMap googleMap = mapView.getMap();
googleMap.addMarker(new MarkerOptions()
        .position(new LatLng(
                Double.parseDouble(
                        mEvent.getEventInfo().mEventData.mLat),
                Double.parseDouble(
                        mEvent.getEventInfo().mEventData.mLng)))
        .title("Marker"));

清单文件:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />

<permission
    android:name="com.example.permission.MAPS_RECEIVE"
    android:protectionLevel="signature" />

<uses-permission android:name="com.example.permission.MAPS_RECEIVE" />

我收到以下错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.maps.model.Marker com.google.android.gms.maps.GoogleMap.addMarker(com.google.android.gms.maps.model.MarkerOptions)' on a null object reference

【问题讨论】:

【参考方案1】:

因为您的 googleMap 尚未加载意味着 null 并且您在其上添加了导致崩溃的标记。最好使用mapView.getMapAsync(context); 而不是mapView.getMap(); 并实现此方法

    @Override
    public void onMapReady(final GoogleMap map) 
        if(map != null)
        // you are ready to add marker here        
        
    

【讨论】:

【参考方案2】:

现在应该通过将 MapFragment 添加到您的视图然后处理它来异步加载 Google 地图。类似的东西会起作用:

public class MainActivity extends Activity implements OnMapReadyCallback 

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


        MapView mapView = new MapView(this);
        ((LinearLayout) findViewById(R.id.mapWrapper)).addView(mapView);
        mapView.getMapAsync(this);

    

    @Override
    public void onMapReady(GoogleMap map) 

        map.addMarker(new MarkerOptions()
                .position(new LatLng(0, 0))
                .title("Marker"));
    


有了这个布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mapWrapper"
    android:orientation="vertical" android:layout_
    android:layout_>

</LinearLayout>

【讨论】:

【参考方案3】:

让您的活动实现 OnMapReadyCallback 并在 OnMapReady() 函数中添加标记。

参考:https://developers.google.com/maps/documentation/android-api/start

【讨论】:

【参考方案4】:

事实证明,在 google play services 版本上 11.8.0 onCreatea()onResume() 是查看 MapView 所必需的:

@Override public void setupMap(LatLng latLng) 
    if (mapView == null) 
      mapView = new MapView(getActivity());
      rootLayout.addView(mapView);
      mapView.onCreate(Bundle.EMPTY);
    
    mapView.getMapAsync(map -> 
      map.clear();
      map.addCircle(MapUtil.makeDefaultGreenCircle(getActivity(), latLng));
    );
  

@Override public void onResume() 
    super.onResume();
    mapView.onResume();
  

【讨论】:

以上是关于以编程方式创建 MapView 并添加标记导致片段中出现空指针异常的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式添加的片段上的后退键导致空容器

以编程方式添加约束会导致崩溃

保存以编程方式为片段创建的视图并在 onresume 中恢复

以编程方式将按钮添加到片段

显示/隐藏片段并以编程方式更改可见性属性

以编程方式关闭标记的信息窗口谷歌地图 iOS