首先,MapFragment下载诊所的数据(名称,描述,地图上的坐标等(,然后尝试添加它们的标记。当片段尝试它时,应用程序会抛出此行不在主线程中的异常。
E/AndroidRuntime: FATAL EXCEPTION: Thread-12
Process: com.happs.medrate, PID: 4332
com.google.maps.api.android.lib6.common.apiexception.c: Not on the main thread
at com.google.maps.api.android.lib6.common.m.b(:com.google.android.gms.dynamite_mapsdynamite@19831046@19.8.31 (040306-0):22)
at com.google.maps.api.android.lib6.common.r.a(:com.google.android.gms.dynamite_mapsdynamite@19831046@19.8.31 (040306-0):5)
at com.google.maps.api.android.lib6.impl.bm.a(:com.google.android.gms.dynamite_mapsdynamite@19831046@19.8.31 (040306-0):60)
at com.google.android.gms.maps.internal.j.a(:com.google.android.gms.dynamite_mapsdynamite@19831046@19.8.31 (040306-0):308)
at ck.onTransact(:com.google.android.gms.dynamite_mapsdynamite@19831046@19.8.31 (040306-0):5)
at android.os.Binder.transact(Binder.java:612)
at com.google.android.gms.internal.maps.zza.zza(Unknown Source:10)
at com.google.android.gms.maps.internal.zzg.addMarker(Unknown Source:54)
at com.google.android.gms.maps.GoogleMap.addMarker(Unknown Source:48)
at com.happs.medrate.view.main.MapFragment.onResult(MapFragment.java:87)
at com.happs.medrate.view.main.MapFragment.lambda$zKz5SBiVflok9pIuOSBON5AS6Uk(Unknown Source:0)
at com.happs.medrate.view.main.-$$Lambda$MapFragment$zKz5SBiVflok9pIuOSBON5AS6Uk.onResult(Unknown Source:4)
at com.happs.medrate.model.clinicsdata.GetClinicsData$GetDataThread.run(GetClinicsData.java:61)
有代码(只有方法(:
//onResult is for GetClinicsData class (it is a Thread class)
private void onResult(Clinic clinic, @Nullable Exception e){
this.clinic = new Clinic(clinic.getName(), clinic.getAddress(), clinic.getDescription(), clinic.getGeoPoint());
MarkerOptions markerOptions = new MarkerOptions();
LatLng coordinates = new LatLng(clinic.getGeoPoint().getLatitude(), clinic.getGeoPoint().getLongitude());
markerOptions.position(coordinates);
map.addMarker(markerOptions);
}
@Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)) {
} else {
// No explanation needed; request the permission
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
} else {
map.setMyLocationEnabled(true);
MyLocationListener.setUpLocationListener(getContext(), getActivity());
}
}
我已经尝试在 onMapReady 中制作"添加标记"部分,但片段首先使用 onMapReady 方法准备地图,然后才下载诊所的数据,所以当它尝试添加标记时,它会抛出"NullPointerException",因为它还没有获得诊所的数据。我不知道我该怎么办...
听起来像是在某些异步工作完成后调用onResult()
,并且这项工作是在主/UI 线程以外的某个线程上完成的。标记只能添加到主线程上的映射中,因此您需要找到一种方法在适当的线程上执行代码。
如果您可以控制onResult()
的调用方,这可能是切换线程的最佳位置:
getActivity().runOnUiThread(this::onResult);
如果没有,您可以在onResult()
内部进行线程切换:
private void onResult(Clinic clinic, @Nullable Exception e){
this.clinic = new Clinic(clinic.getName(), clinic.getAddress(), clinic.getDescription(), clinic.getGeoPoint());
MarkerOptions markerOptions = new MarkerOptions();
LatLng coordinates = new LatLng(clinic.getGeoPoint().getLatitude(), clinic.getGeoPoint().getLongitude());
markerOptions.position(coordinates);
getActivity().runOnUiThread(() -> {
map.addMarker(markerOptions);
});
}
如果出于某种原因,您不想使用runOnUiThread()
,那么您可以使用Handler
来获得相同的结果:
new Handler().post(() -> { /* your code here */ });
使用 runOnUiThread
runOnUiThread(new Runnable() {
@Override
public void run() {
MapView mMapView = (MapView) dialog.findViewById(R.id.mapView);
MapsInitializer.initialize(context);
mMapView.onCreate(dialog.onSaveInstanceState());
mMapView.onResume();
mMapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(final GoogleMap googleMap) {
LatLng myLocation=new LatLng(Double.parseDouble(lat), Double.parseDouble(lon));
googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
googleMap.addMarker(new MarkerOptions().position(myLocation).title("My location").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
float zoomLevel = (float) 16.0; //This goes up to 21
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(myLocation, zoomLevel));
googleMap.getUiSettings().setZoomControlsEnabled(true);
}
});
}
});