MapFragment 在 getMapAsync(this) 方法中导致 NullPointerException
MapFragment causing NullPointerException at getMapAsync(this) method
我实现了 activity,它在 运行 时添加了 MapFragment
。 MapFragment
xml 具有静态 fragment
,我正试图在 运行 时添加。我还发现 Lollipop 在 运行 时间添加地图片段时存在一些问题。请检查 Issue raised and temporary 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);
}
这个总是return我是空的,我也试过了,
((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map)).getMapAsync(this);
这也是returnNullPointerException
MapsActivity.java
getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer, MapsFragment.newInstance()).commit();
我在 Activity 回调的 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
不久前我一直在为类似的问题而苦苦挣扎。
关键是 getMap()
在适当的时候,在 Fragment
的 onViewCreated()
:
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);
}
}
}
}
XML 看起来像你的:
<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>
然后,在 onViewCreated()
中,您可以通知 Activity
,您的 map-fragment 可以使用了。
希望对你有所帮助
通过观察 SO 中给出的答案,我终于自己解决了这个问题。我比较了我的代码和答案中的代码。在我看来,API 和 Google 的实施范围很广,有些混乱。我反复抛出这个异常:
Attempt to invoke interface method 'void com.google.maps.api.android.lib6.e.fl.o()' on a null object reference
我仍然不知道在出现相同异常的 SO 问题中的某些实现有什么问题,但这对我有用,可能对其他人也有用。
这些是您需要检查的内容:
确保你有这两个(我只有 api 键 meta-data)
<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" />
您在 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"/>
在我的例子中,地图片段是一个子片段,在另一个片段中。
这个父片段显然不应该是 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
的回答中看到的那样
试试看然后告诉我。
在我的例子中,我在片段的 xml 中静态使用原始 MapView
。问题是我不得不将呼叫转移 mMapView.onCreate(...)
移动到 onViewCreated(...)
因为在 onCreate()
中 mMapView
还没有膨胀。如果你不使用 MapView
那么你应该仔细检查你调用 getMap()
的时刻。我肯定是在内部MapView膨胀之后。
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();
}
}
}
如果您使用 mapView,只需确保您在 mapView.getMapAsync()
之前调用了 mapView.onCreate()
。如果您使用的片段和视图仍未初始化,您还可以在 onViewCreated()
方法中调用 mapView.onCreate()
。
我实现了 activity,它在 运行 时添加了 MapFragment
。 MapFragment
xml 具有静态 fragment
,我正试图在 运行 时添加。我还发现 Lollipop 在 运行 时间添加地图片段时存在一些问题。请检查 Issue raised and temporary 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);
}
这个总是return我是空的,我也试过了,
((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map)).getMapAsync(this);
这也是returnNullPointerException
MapsActivity.java
getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer, MapsFragment.newInstance()).commit();
我在 Activity 回调的 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
不久前我一直在为类似的问题而苦苦挣扎。
关键是 getMap()
在适当的时候,在 Fragment
的 onViewCreated()
:
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);
}
}
}
}
XML 看起来像你的:
<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>
然后,在 onViewCreated()
中,您可以通知 Activity
,您的 map-fragment 可以使用了。
希望对你有所帮助
通过观察 SO 中给出的答案,我终于自己解决了这个问题。我比较了我的代码和答案中的代码。在我看来,API 和 Google 的实施范围很广,有些混乱。我反复抛出这个异常:
Attempt to invoke interface method 'void com.google.maps.api.android.lib6.e.fl.o()' on a null object reference
我仍然不知道在出现相同异常的 SO 问题中的某些实现有什么问题,但这对我有用,可能对其他人也有用。
这些是您需要检查的内容:
确保你有这两个(我只有 api 键 meta-data)
<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" />
您在 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"/>
在我的例子中,地图片段是一个子片段,在另一个片段中。
这个父片段显然不应该是 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
的回答中看到的那样试试看然后告诉我。
在我的例子中,我在片段的 xml 中静态使用原始 MapView
。问题是我不得不将呼叫转移 mMapView.onCreate(...)
移动到 onViewCreated(...)
因为在 onCreate()
中 mMapView
还没有膨胀。如果你不使用 MapView
那么你应该仔细检查你调用 getMap()
的时刻。我肯定是在内部MapView膨胀之后。
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();
}
}
}
如果您使用 mapView,只需确保您在 mapView.getMapAsync()
之前调用了 mapView.onCreate()
。如果您使用的片段和视图仍未初始化,您还可以在 onViewCreated()
方法中调用 mapView.onCreate()
。