我目前正在开发一款使用Google Maps API v2的Android应用。我正在显示外部XML文件中的自定义标记:http://dds.orgfree.com/DDS/landmarks_genxmlv2.php,它将在地图中显示一些地标。
正如您在下面的代码中所看到的,我在实际手机中测试此应用时使用StrictMode来避免NetworkOnMainThreadException。我知道使用这种方法是不可取的。它应该通过AsyncTask在单独的线程和后台完成。我尝试在这个应用程序中实现AsyncTask但我没有运气。任何人都可以帮我提供我的代码或提供一些有用的建议吗?非常感谢。
public class MapViewActivity extends android.support.v4.app.FragmentActivity {
static final LatLng CITYHALL = new LatLng(07.0644444, 125.6077778);
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_mapview);
setUpMapIfNeeded();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mapview_options_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.normal_mapstyle) {
mMap.setMapType(MAP_TYPE_NORMAL);
} else if (item.getItemId() == R.id.hybrid_mapstyle) {
mMap.setMapType(MAP_TYPE_HYBRID);
} else if (item.getItemId() == R.id.satellite_mapstyle) {
mMap.setMapType(MAP_TYPE_SATELLITE);
} else if (item.getItemId() == R.id.terrain_mapstyle) {
mMap.setMapType(MAP_TYPE_TERRAIN);
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
Document doc = null;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder
.parse("http://dds.orgfree.com/DDS/landmarks_genxmlv2.php");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
NodeList markers = doc.getElementsByTagName("marker");
try {
for (int i = 0; i < markers.getLength(); i++) {
Element item = (Element) markers.item(i);
String name = item.getAttribute("name");
String address = item.getAttribute("address");
String stringLat = item.getAttribute("lat");
String stringLng = item.getAttribute("lng");
String icon = item.getAttribute("icon");
Double lat = Double.valueOf(stringLat);
Double lng = Double.valueOf(stringLng);
mMap = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
mMap.addMarker(new MarkerOptions()
.position(new LatLng(lat, lng))
.title(name)
.snippet(address)
.icon(BitmapDescriptorFactory.fromAsset(new String(icon
+ ".png"))));
// Move the camera instantly to City Hall with a zoom of 15.
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(CITYHALL, 15));
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
这是我尝试过的。
public class MapViewActivity extends android.support.v4.app.FragmentActivity {
static final LatLng CITYHALL = new LatLng(07.0644444, 125.6077778);
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_mapview);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
setUpMapIfNeeded();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mapview_options_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.map_menu_showlegend) {
Log.d("MENU", "Show Legend was CLICKED!");
} else if (item.getItemId() == R.id.map_menu_maptype) {
Log.d("MENU", "Map Type was CLICKED!");
} else if (item.getItemId() == R.id.normal_mapstyle) {
Log.d("MENU", "MAP_TYPE_NORMAL was CLICKED!");
mMap.setMapType(MAP_TYPE_NORMAL);
} else if (item.getItemId() == R.id.hybrid_mapstyle) {
Log.d("MENU", "MAP_TYPE_HYBRID was CLICKED!");
mMap.setMapType(MAP_TYPE_HYBRID);
} else if (item.getItemId() == R.id.satellite_mapstyle) {
Log.d("MENU", "MAP_TYPE_SATELLITE was CLICKED!");
mMap.setMapType(MAP_TYPE_SATELLITE);
} else if (item.getItemId() == R.id.terrain_mapstyle) {
Log.d("MENU", "MAP_TYPE_TERRAIN was CLICKED!");
mMap.setMapType(MAP_TYPE_TERRAIN);
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the
// map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private Boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni != null && ni.isConnected())
return true;
return false;
}
private void setUpMap() {
new ParseXML().execute();
}
private class ParseXML extends AsyncTask<Void, Void, Document> {
Document doc = null;
@Override
protected Document doInBackground(Void... params) {
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if (isOnline()) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder
.parse("http://dds.orgfree.com/DDS/landmarks_genxmlv2.php");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
NodeList markers = doc.getElementsByTagName("marker");
try {
for (int i = 0; i < markers.getLength(); i++) {
Element item = (Element) markers.item(i);
String name = item.getAttribute("name");
String address = item.getAttribute("address");
String stringLat = item.getAttribute("lat");
String stringLng = item.getAttribute("lng");
String icon = item.getAttribute("icon");
Double lat = Double.valueOf(stringLat);
Double lng = Double.valueOf(stringLng);
mMap = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
mMap.addMarker(new MarkerOptions()
.position(new LatLng(lat, lng))
.title(name)
.snippet(address)
.icon(BitmapDescriptorFactory
.fromAsset(new String(icon + ".png"))));
// Move the camera instantly to City Hall with a zoom of
// 15.
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
CITYHALL, 15));
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
} else {
Toast.makeText(MapViewActivity.this, "No connection..",
Toast.LENGTH_LONG).show();
}
return doc;
}
@Override
protected void onPostExecute(Document doc) {
super.onPostExecute(doc);
}
}
}
答案 0 :(得分:0)
您无法从后台线程更改UI
因此,将更改UI的所有内容移至onPostExecute()
方法。
我今天已经用代码示例回答了同样的问题:Android disable button on successful doinbackground call