MapFragment 在 getMapAsync(this) 方法中导致 NullPointerException
Posted
技术标签:
【中文标题】MapFragment 在 getMapAsync(this) 方法中导致 NullPointerException【英文标题】:MapFragment causing NullPointerException at getMapAsync(this) method 【发布时间】:2016-04-07 06:45:40 【问题描述】:我已经实现了一个在运行时添加MapFragment
的活动。 MapFragment
xml 具有静态 fragment
,我试图在运行时添加。我还发现 Lollipop 在运行时添加地图片段存在一些问题。请检查Issue raised和temporary solution
我也在下面给出了我的代码,
fragment_map.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
tools:context=".fragment.MapsFragment">
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_
android:layout_
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);
这总是返回 null 我也尝试过,
((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map)).getMapAsync(this);
这也返回NullPointerException
MapsActivity.java
getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer, MapsFragment.newInstance()).commit();
我在onCreate
Activity 回调方法中添加了这个。
我无法弄清楚为什么我仍然收到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
【问题讨论】:
将((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map)).getMapAsync(this);
行放入您的onCreateView()
并从fragment_map.xml
中删除tools:context="appCreators.bloodfinder.activity.MapsActivity"
我试过了,但没有运气我得到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
有什么解决办法吗?我已经坚持了 2 天了。
我刚刚解决了。看看我的回答,让我知道。
【参考方案1】:
我终于通过观察 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
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 中有一个像这样的片段,其类属性正确,如下所示
<fragment
android:id="@+id/google_map_fragment"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_
android:layout_/>
在我的例子中,地图片段是一个孩子,在另一个片段中。
这个父片段显然不应该是 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 的回答中看到的那样
试试看,然后告诉我。
【讨论】:
看起来很有希望。我会尽力让你知道 工作链接魅力!我犯的错误是扩展SupportMapFragment
而不是Fragment
。更改为Fragment
有效。在我的情况下,其他情况是完美的。非常感谢。【参考方案2】:
在我的情况下,我在片段的 xml 中静态使用原始 MapView
。问题是我不得不将呼叫转移mMapView.onCreate(...)
移动到onViewCreated(...)
,因为onCreate()
mMapView
尚未膨胀。如果您不使用MapView
,那么您应该仔细检查您调用getMap()
的时间。我必须在内部 MapView 膨胀之后。
【讨论】:
【参考方案3】:不久前我一直在努力解决类似的问题。
关键是在适当的时候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_
android:layout_>
<fragment
android:id="@+id/locationMap"
android:layout_above="@+id/locationLabelTextView"
android:layout_
android:layout_
android:name="com.google.android.gms.maps.SupportMapFragment" />
</FrameLayout>
然后,您可以在onViewCreated()
中通知Activity
,您的地图片段可以使用了。
希望对你有帮助
【讨论】:
我会检查这个并告诉你! 嘿,我试过了,但我收到了这个错误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
。我认为还有其他原因导致了这个问题!它并没有给我确切的路线或问题的原因。我用谷歌搜索了很多,但结果一无所获!
试过这个。同样的问题。那个例外仍然存在。【参考方案4】:
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();
【讨论】:
【参考方案5】:如果您使用 mapView,请确保您在调用 mapView.onCreate()
之前调用了 mapView.getMapAsync()
。如果您正在使用片段并且视图仍未初始化,您也可以在onViewCreated()
方法中调用mapView.onCreate()
。
【讨论】:
以上是关于MapFragment 在 getMapAsync(this) 方法中导致 NullPointerException的主要内容,如果未能解决你的问题,请参考以下文章
java.lang.NullPointerException: MapFragment.getMapAsync(com.google.android.gms.maps.OnMapReadyCallba