Java 应用程序正在抛出一个异常;“不在主线程中”;当它';It’他正试图添加一个标记
首先,MapFragment下载诊所的数据(名称、描述、地图上的坐标等),然后尝试添加它们的标记。当片段尝试时,应用程序会抛出一个异常,即此行不在主线程中Java 应用程序正在抛出一个异常;“不在主线程中”;当它';It’他正试图添加一个标记,java,android,google-maps,android-studio,exception,Java,Android,Google Maps,Android Studio,Exception,首先,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
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)
下面是代码(仅限方法):
我已经尝试在onMapReady中创建“添加标记”部分,但是片段首先使用onMapReady方法准备映射,然后才下载诊所的数据,因此当它尝试添加标记时,抛出“NullPointerException”,因为它还没有获得诊所的数据。我不知道我应该怎么做…听起来像是在一些异步工作完成后调用了
onResult()
,而这些工作是在主/ui线程以外的某个线程上完成的。标记只能添加到主线程上的映射中,因此您需要找到在适当线程上执行代码的方法
如果您可以控制onResult()
的调用方,那么这可能是切换线程的最佳位置:
getActivity().runOnUiThread(this::onResult);
如果没有,则可以在onResult()中执行线程切换:
如果出于任何原因,您不想使用runOnUiThread()
,则可以使用处理程序来获得相同的结果:
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);
}
});
}
});
请添加更多解释,说明为什么您的解决方案有效。
new Handler().post(() -> { /* your code here */ });
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);
}
});
}
});