我正在使用一个具有选项卡式视图寻呼机布局的安卓应用程序。我必须在查看页的第一个屏幕中显示地图。映射包含在活动片段中(AppCompatActivity -> 片段 -> 映射(。该应用程序具有一项服务,用于在需要时更新地图。
片段布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
内部碎片:
public class HomeFragment extends Fragment implements OnMapReadyCallback, MapViewUpdateListener {
private GoogleMap mGoogleMap;
内onCreateView()
:
SupportMapFragment mapFragment = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map));
mapFragment.getMapAsync(this);
内部onMapReady
@Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
theGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
googleMap.setMyLocationEnabled(true);
googleMap.setTrafficEnabled(true);
googleMap.setIndoorEnabled(true);
googleMap.setBuildingsEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
}
内部MapViewUpdateListener
(用于从后台服务侦听位置更新(
@Override
public void pointTo(Location location) {
Marker currentLocationMarker = mGoogleMap
.addMarker(new MarkerOptions()
.position(new LatLng(location.getLatitude(),location.getLongitude()))
.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE)));
}
}
当 map 加载时onMapReady(GoogleMap googleMap)
被调用,我将googleMap
存储到全局变量中以备将来使用。问题是当pointTo(Location location)
从服务中调用时,mGoogleMap
在这里发现 null。但是mGoogleMap
在调用onMapReady(GoogleMap googleMap)
时初始化。
我已经尝试了几种方法,包括使用MapView
而不是使用SupportMapFragment
.但没有想出任何解决方案!
有什么线索或解决方法可以解决此问题吗?蒂亚。
溶液
经过多种方式的尝试,终于得到了一个稳定的解决方案。我已经从 HomeFragment 中删除了MapViewUpdateListener
,并实现了从服务接收更新的LocalBroadCastReceiver
。实际上,我已经从HomeActivity
中删除了现有的LocalBroadCastReceiver
并将其放入HomeFragment
中。当LocalBroadCastReceiver
被解雇时HomeFragment
我可以在没有任何NPE的情况下使用现有的mGoogleMap
。
但是,我仍然不知道为什么通过接口传递的位置更新会为实例变量获取 NPE。我想,我将HomeFragment
初始化为MapViewUpdateListener
的方式可能存在一些问题。可能是我通过类型转换返回新HomeFragment
而不是现有对象获得HomeFragment
对象!!(但很难相信这会发生!
这里有竞争条件。尝试在方法pointTo
设置标记(您已经在这样做了(,但null
检查mGoogleMap
是否null
。 此外,如果您收到位置更新后 google 地图已准备就绪(onMapReady
在pointTo
之后被调用(更新 yonMapRead
内的标记(变量latitude
和 pointTo 方法调用时longitude
。
因此,指向方法可能如下所示:
@Override
public void pointTo(Location location) {
if(mGoogleMap!=null){
Marker currentLocationMarker = mGoogleMap
.addMarker(new MarkerOptions()
.position(new
LatLng(location.getLatitude(),location.getLongitude()))
.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE)));
}
}
else{
latitude=location.latitude;//or whatever property is called
longitude=location.longitude;;//or whatever property is called
}
}
在地图就绪中执行以下操作:
mGoogleMap = googleMap;
theGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
googleMap.setMyLocationEnabled(true);
googleMap.setTrafficEnabled(true);
googleMap.setIndoorEnabled(true);
googleMap.setBuildingsEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
if(latitude!=null && longitude!=null){
//Insert marker here on map because we have map ready and latitude and longitude also
}
}