MapFragment在getMapAsync(this)方法中导致NullPointerException

时间:2016-01-03 14:56:26

标签: android android-fragments nullpointerexception supportmapfragment mapactivity

我已经实现了一个在运行时添加MapFragment的活动。 MapFragment xml有静态fragment,我试图在运行时添加。我还发现Lollipop在运行时添加了地图片段存在一些问题。请检查Issue raisedtemporary solution

我也在下面给出了我的代码,

fragment_map.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:tools="http://schemas.android.com/tools"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         tools:context=".fragment.MapsFragment">

<fragment
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="appCreators.bloodfinder.activity.MapsActivity"/>

<include
    android:id="@+id/layout"
    layout="@layout/template_custom_spinner"/>

</FrameLayout>

MapsFragment.java

实施onMapReadyCallback

public class MapsFragment extends SupportMapFragment implements OnMapReadyCallback

onResume回调

@Override
public void onResume() {
    super.onResume();
    ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMapAsync(this);
}

这总是让我归零,我也试过了,

((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map)).getMapAsync(this);

这也会返回NullPointerException

MapsActivity.java

getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer, MapsFragment.newInstance()).commit();

我在活动回调的onCreate方法中添加了这个。

我无法弄清楚为什么我仍然会NullPointerException

有时候我会Attempt to invoke interface method 'void com.google.maps.api.android.lib6.e.fl.o()' on a null object reference

帮助将不胜感激!

更新:仍然没有修复我收到以下错误。我查看了日志,但不知道为什么会发生这种情况。

Unable to resume activity {MapsActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.maps.api.android.lib6.e.fl.o()' on a null object reference

5 个答案:

答案 0 :(得分:11)

我终于通过观察SO中给出的答案为自己解决了这个问题。我比较了代码和答案中的代码。在我看来,这个API存在一些混淆,谷歌的实施非常广泛。我反复抛出这个异常:

Attempt to invoke interface method 'void com.google.maps.api.android.lib6.e.fl.o()' on a null object reference

我仍然不知道在SO问题中这些实现中的某些实现是否有相同的异常,但这对我有用,并且可能适用于其他人。

这些是您需要检查的内容:

  1. 确保您拥有这两个(我只有api密钥元数据)

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
    
  2. 你有一个像这样的xml片段,其中class属性正确如下

       <fragment
        android:id="@+id/google_map_fragment"
        class="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    
  3. 在我的情况下,地图片段是一个孩子,在另一个片段中。

    这个父片段显然不应该是MapFragment或SupportMapFragment。将它从SupportMapFragment更改为Fragment后,地图显示完全正常。

    public class ParentFragment extends Fragment {
    

    我之前保留了以前的所有内容,但是没有在onCreateView中获取地图,而是在onViewCreated中得到了这样的内容:

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    
        mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.rewards_google_map_area);
        if (mapFragment != null) {
            LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
            if (locationManager != null && mapFragment.getMap() != null) {
                googleMap=mapFragment.getMap();
                //after this you do whatever you want with the map
            }
        }
    
    }
    

    我没有改变任何其他东西,我没有弄乱rootView或parentView。正如你在@Konstantin Loginov的回答中看到的那样

    尝试一下,让我知道。

答案 1 :(得分:2)

前一段时间我一直在努力解决类似的问题。 关键是在getMap() onViewCreated() Fragment的适当时刻public class LocationFragment extends Fragment { private SupportMapFragment locationMap; private View rootView; protected View getFragmentView() { View view = getView(); if (view == null) { view = rootView; } return view; } @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View rootView = getFragmentView(); if (rootView != null) { ViewGroup parent = (ViewGroup) rootView.getParent(); if (parent != null) { parent.removeView(rootView); } } try { rootView = inflater.inflate(R.layout.fragment_signup_specify_location, container, false); } catch (InflateException ex) { Log.e(LOG_TAG, "Inflate Exception in onCreateView; Caused by map fragment", ex); } ...... return getFragmentView(); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); locationMap = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.locationMap); if (locationMap != null) { LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE); if (locationManager != null && locationMap.getMap() != null) { locationMap.getMap().setMyLocationEnabled(true); } } } } :{/ 1}

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment
        android:id="@+id/locationMap"
        android:layout_above="@+id/locationLabelTextView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.google.android.gms.maps.SupportMapFragment" />
</FrameLayout>

它的XML看起来像你的:

onViewCreated()

然后,在Activity中,您可以通知hide.bs.modal您的地图片段已准备好使用。

我希望,这有帮助

答案 2 :(得分:1)

在我的情况下,我在Fragment的xml中静态使用原始MapView。问题是我必须将呼叫转移mMapView.onCreate(...)移至onViewCreated(...),因为onCreate() mMapView尚未充气。如果您不使用MapView,则应仔细检查您拨打getMap()的时刻。我必须在内部MapView被夸大之后。

答案 3 :(得分:1)

如果使用mapView,只需确保在mapView.onCreate()之前调用了mapView.getMapAsync()。如果您使用片段并且视图仍未初始化,则还可以使用mapView.onCreate()方法调用onViewCreated()

答案 4 :(得分:0)

UPDATE 2019

如果您仍然遇到此问题,请尝试以下方法:

请勿扩展SupportMapFrangemt!

public class MyFragment extends Fragment {

private SupportMapFragment fragment;
private GoogleMap map;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.layout_with_map, container, false);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    FragmentManager fm = getChildFragmentManager();
    fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
    if (fragment == null) {
        fragment = SupportMapFragment.newInstance();
        fm.beginTransaction().replace(R.id.map_container, fragment).commit();
    }
}

}