无法获取 GoogleMap 对象
Unable to get the GoogleMap object
我创建了一个 MapFragment class。在这里我通过 googleMap = mMapView.getMap()
创建了 GoogleMap 对象 我有一个方法 ParserTask 如果我从这个方法的 onCreate 调用 ParserTask 然后 ParserTask 成功运行并且 googleMap.addPolyline(lineOptions)
运行。但是如果我从另一个 Activity 调用方法 ParserTask 然后 googleMap.addPolyline(lineOptions)
不起作用,它显示空指针异常。我认为这里 googleMap 没有获取 MapView 的实例。现在谁能给我一个建议,这样我就可以在 ParserTask 中获取 googleMap 的实例,如果它是从另一个 activity 调用的.我在下面附上了我的代码:
public class MapFragment extends Fragment implements
GoogleMap.OnInfoWindowClickListener{
MapView mMapView;
private static final int MAP_ZOOM_AMOUNT=17;
private TextView locName;
private TextView mapIndicator;
private GoogleMap googleMap=null;
private String locationName;
private String mapIndicatorText;
private int categoryId;
private int locationNameId;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_map, container,
false);
mMapView = (MapView) rootView.findViewById(R.id.mapView);
locName = (TextView) rootView.findViewById(R.id.tv_location_name);
mapIndicator = (TextView) rootView.findViewById(R.id.tv_map_indicator);
locName.setText(locationName);
mapIndicator.setText(Html.fromHtml("সব " + mapIndicatorText + " এর স্থান ম্যাপ এ দেখানো হয়েছে"));
mMapView.onCreate(savedInstanceState);
mMapView.onResume();
try {
MapsInitializer.initialize(getActivity().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
googleMap = mMapView.getMap();
googleMap.setOnInfoWindowClickListener(this);
return rootView;
}
@Override
public void onInfoWindowClick(Marker marker) {
LatLng loc = marker.getPosition();
}
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String,String>>> >{
// Parsing the data in non-ui thread
@Override
protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {
JSONObject jObject;
List<List<HashMap<String, String>>> routes = null;
try{
jObject = new JSONObject(jsonData[0]);
RouteActivity parser = new RouteActivity();
// Starts parsing data
routes = parser.parse(jObject);
}catch(Exception e){
e.printStackTrace();
}
return routes;
}
// Executes in UI thread, after the parsing process
@Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = null;
PolylineOptions lineOptions = null;
// Traversing through all the routes
for(int i=0;i<result.size();i++){
points = new ArrayList<LatLng>();
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for(int j=0;j<path.size();j++){
HashMap<String,String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
// Adding all the points in the route to LineOptions
lineOptions.addAll(points);
lineOptions.width(2);
lineOptions.color(Color.RED);
}
//setUpMapIfNeeded();
// Drawing polyline in the Google Map for the i-th route
***googleMap.addPolyline(lineOptions);***
}
}
@Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
}
您在评论中说您运行宁 ParserTask
如下:
MapFragment mapFragment = new MapFragment();
mapFragment.parserTask(result);
问题在于 MapView
在 MapFragment
的 onCreateView
为 运行 时被初始化,当 Fragment
映入眼帘。因此,当您尝试 运行 ParserTask
时,MapView
尚未初始化。您在这里的选择是重新组织您的 class 结构(可能是更好的解决方案,但也需要更多工作),或者您可以尝试这样做:
先做一个class-levelPolylineOptions polylineOptions;
变量。在您的 onPostExecute()
中,将 googleMap.addPolyline(lineOptions);
替换为
if (googleMap != null) {
googleMap.addPolyline(lineOptions);
} else {
polylineOptions = lineOptions;
}
在你的 onCreateView
中,你可以写:
if (polylineOptions != null) {
googleMap.addPolyline(polylineOptions);
}
想法是,如果异步任务在视图呈现之前完成,则保存视图呈现时的数据,如果视图在异步任务完成之前呈现,则立即应用效果。
我没有使用 AsyncTask。相反,我使用了一个处理程序和一个线程。
您可以删除 AsyncTask 的部分并尝试我的代码。
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {
mapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googleMap) {
googleMap.addMarker(marker1);
googleMap.addMarker(marker2);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng1, zoom));
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng2, zoom));
polylineOptions.addAll(points);
polylineOptions.width(10);
polylineOptions.color(Color.BLUE);
googleMap.addPolyline(polylineOptions);
//disable the rotation, scroll of the map
googleMap.getUiSettings().setAllGesturesEnabled(false);
}
});
}
};
mainHandler.post(myRunnable);
我创建了一个 MapFragment class。在这里我通过 googleMap = mMapView.getMap()
创建了 GoogleMap 对象 我有一个方法 ParserTask 如果我从这个方法的 onCreate 调用 ParserTask 然后 ParserTask 成功运行并且 googleMap.addPolyline(lineOptions)
运行。但是如果我从另一个 Activity 调用方法 ParserTask 然后 googleMap.addPolyline(lineOptions)
不起作用,它显示空指针异常。我认为这里 googleMap 没有获取 MapView 的实例。现在谁能给我一个建议,这样我就可以在 ParserTask 中获取 googleMap 的实例,如果它是从另一个 activity 调用的.我在下面附上了我的代码:
public class MapFragment extends Fragment implements
GoogleMap.OnInfoWindowClickListener{
MapView mMapView;
private static final int MAP_ZOOM_AMOUNT=17;
private TextView locName;
private TextView mapIndicator;
private GoogleMap googleMap=null;
private String locationName;
private String mapIndicatorText;
private int categoryId;
private int locationNameId;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_map, container,
false);
mMapView = (MapView) rootView.findViewById(R.id.mapView);
locName = (TextView) rootView.findViewById(R.id.tv_location_name);
mapIndicator = (TextView) rootView.findViewById(R.id.tv_map_indicator);
locName.setText(locationName);
mapIndicator.setText(Html.fromHtml("সব " + mapIndicatorText + " এর স্থান ম্যাপ এ দেখানো হয়েছে"));
mMapView.onCreate(savedInstanceState);
mMapView.onResume();
try {
MapsInitializer.initialize(getActivity().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
googleMap = mMapView.getMap();
googleMap.setOnInfoWindowClickListener(this);
return rootView;
}
@Override
public void onInfoWindowClick(Marker marker) {
LatLng loc = marker.getPosition();
}
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String,String>>> >{
// Parsing the data in non-ui thread
@Override
protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {
JSONObject jObject;
List<List<HashMap<String, String>>> routes = null;
try{
jObject = new JSONObject(jsonData[0]);
RouteActivity parser = new RouteActivity();
// Starts parsing data
routes = parser.parse(jObject);
}catch(Exception e){
e.printStackTrace();
}
return routes;
}
// Executes in UI thread, after the parsing process
@Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = null;
PolylineOptions lineOptions = null;
// Traversing through all the routes
for(int i=0;i<result.size();i++){
points = new ArrayList<LatLng>();
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for(int j=0;j<path.size();j++){
HashMap<String,String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
// Adding all the points in the route to LineOptions
lineOptions.addAll(points);
lineOptions.width(2);
lineOptions.color(Color.RED);
}
//setUpMapIfNeeded();
// Drawing polyline in the Google Map for the i-th route
***googleMap.addPolyline(lineOptions);***
}
}
@Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
}
您在评论中说您运行宁 ParserTask
如下:
MapFragment mapFragment = new MapFragment();
mapFragment.parserTask(result);
问题在于 MapView
在 MapFragment
的 onCreateView
为 运行 时被初始化,当 Fragment
映入眼帘。因此,当您尝试 运行 ParserTask
时,MapView
尚未初始化。您在这里的选择是重新组织您的 class 结构(可能是更好的解决方案,但也需要更多工作),或者您可以尝试这样做:
先做一个class-levelPolylineOptions polylineOptions;
变量。在您的 onPostExecute()
中,将 googleMap.addPolyline(lineOptions);
替换为
if (googleMap != null) {
googleMap.addPolyline(lineOptions);
} else {
polylineOptions = lineOptions;
}
在你的 onCreateView
中,你可以写:
if (polylineOptions != null) {
googleMap.addPolyline(polylineOptions);
}
想法是,如果异步任务在视图呈现之前完成,则保存视图呈现时的数据,如果视图在异步任务完成之前呈现,则立即应用效果。
我没有使用 AsyncTask。相反,我使用了一个处理程序和一个线程。
您可以删除 AsyncTask 的部分并尝试我的代码。
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {
mapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googleMap) {
googleMap.addMarker(marker1);
googleMap.addMarker(marker2);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng1, zoom));
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng2, zoom));
polylineOptions.addAll(points);
polylineOptions.width(10);
polylineOptions.color(Color.BLUE);
googleMap.addPolyline(polylineOptions);
//disable the rotation, scroll of the map
googleMap.getUiSettings().setAllGesturesEnabled(false);
}
});
}
};
mainHandler.post(myRunnable);