我的 UI 使用带距离矩阵的 AsyncTask 和 google 地图被阻止
My UI is blocked using AsyncTask with distancematrix and google Maps
我正在使用 google 地图来显示一些标记。标记是从数据库下载的,同时,我从 google api 获取用户当前位置与我从数据库中获取的标记之间的距离矩阵。
我的问题是我是用 .get 做的,阻塞了我的 ui(我读过 .get 阻塞了 ui:
dataFromAsyncTask = testAsyncTask.get();
现在,我试图在不阻挡 ui 的情况下做同样的事情,但我无法同时或以一种好的方式获得此标记的距离。
感谢您的帮助。
这是我的旧代码和错误代码.get:
for (City city : listCity.getData()) {
geoPoint = city.getLocation();
nameBeach = city.getName();
if (geoPoint == null) {
} else {
latitude = String.valueOf(geoPoint.getLatitude());
longitude = String.valueOf(geoPoint.getLongitude());
startRetrievenDistanceAndDuration();
try {
dataFromAsyncTask = testAsyncTask.get();
} catch (InterruptedException i) {
} catch (ExecutionException e) {
}
mMap.addMarker(new MarkerOptions().position(new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude()))
.title(nameCity)
.snippet(dataFromAsyncTask)
.icon(BitmapDescriptorFactory.defaultMarker()));
}
}
startRetrievenDistanceAndDuration 方法:
private void startRetrievenDistanceAndDuration() {
final String url;
testAsyncTask = new DistanceBetweenLocations(new FragmentCallback() {
@Override
public void onTaskDone(String result) {
}
});
url = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxx";
testAsyncTask.execute(new String[]{url});
}
public interface FragmentCallback {
public void onTaskDone(String result);
AsyncTask class:
@Override
protected String doInBackground(String... params) {
HttpURLConnection urlConnection = null;
URL url = null;
StringBuilder result = null;
String duration = "";
String distance = "";
try {
url=new URL(params[0]);
}catch (MalformedURLException m){
}
try {
urlConnection = (HttpURLConnection) url.openConnection();
}catch (IOException e){}
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
result = new StringBuilder();
String line;
while((line = reader.readLine()) != null) {
result.append(line);
}
}catch (IOException e){
} finally {
urlConnection.disconnect();
}
try {
JSONObject jsonObject = new JSONObject(result.toString());
JSONArray jsonArray = jsonObject.getJSONArray("rows");
JSONObject object_rows = jsonArray.getJSONObject(0);
JSONArray jsonArrayElements = object_rows.getJSONArray("elements");
JSONObject object_elements = jsonArrayElements.getJSONObject(0);
JSONObject object_duration = object_elements.getJSONObject("duration");
JSONObject object_distance = object_elements.getJSONObject("distance");
duration = object_duration.getString("text");
distance = object_distance.getString("text");
} catch (JSONException e) {
e.printStackTrace();
}
return distance + ", " + duration;
}
@Override
protected void onPostExecute(String result) {
mFragmentCallback.onTaskDone(result);
}
}
我正在尝试这样做,但我只显示列表的最后一个标记:
循环调用方法:
startRetrievenDistanceAndDuration();
然后在 onTaskDone 中尝试放置标记,但只得到我列表中的最后一个标记
@Override
public void onTaskDone(String result) {
mMap.addMarker(new MarkerOptions().position(new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude()))
.title(nameBeach)
.snippet(result)
.icon(BitmapDescriptorFactory.defaultMarker()));
}
更改后更新:(仍然不起作用)
我可以在 Asynctask 中解析数据并在 onPostExecute 中发送它,但我只得到一个值,而不是我拥有的 9 个值....
主要ACTIVITY:
DistanceBetweenLocations task = new DistanceBetweenLocations(mlatituDouble, mlongitudeDouble){
@Override
protected void onPostExecute(HashMap<String, String> result) {
super.onPostExecute(result);
String name = result.get("beachName");
String distance = result.get("distance");
String duration = result.get("duration");
String latitue = result.get("latitude");
String longitude = result.get("longitude");
Double mlatituDouble = Double.parseDouble(latitue);
Double mlongitudeDouble = Double.parseDouble(longitude);
if (mMap == null) {
mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.mapView))
.getMap();
Toast.makeText(getActivity(), "mMap NO null", Toast.LENGTH_SHORT).show();
mMap.addMarker(new MarkerOptions().position(new LatLng(mlatituDouble, mlongitudeDouble))
.title(name)
.snippet(distance + " " + duration)
.icon(BitmapDescriptorFactory.defaultMarker()));
}
}
};
task.execute();
异步任务CLASS:.
public class DistanceBetweenLocations extends AsyncTask<String, String, HashMap<String, String>> {
Double currentLatitude;
Double currentlongitude;
public BeachMap beachMap;
public BackendlessCollection<Beach> dataBeach;
public GoogleMap mMap;
String latitude;
String longitude;
HashMap<String, String> map;
public DistanceBetweenLocations(Double currentLatitude, Double currentlongitude){
this.currentLatitude = currentLatitude;
this.currentlongitude = currentlongitude;
}
@Override
protected HashMap<String, String> doInBackground(String... params) {
dataBeach = beachMap.listBeach;
for (Beach city : dataBeach.getData()) {
GeoPoint geoPoint = city.getLocation();
String nameBeach = city.getName();
if (geoPoint == null) {
} else {
latitude = String.valueOf(geoPoint.getLatitude());
longitude = String.valueOf(geoPoint.getLongitude());
HttpURLConnection urlConnection = null;
URL url = null;
StringBuilder result = null;
String duration = "";
String distance = "";
try {
url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxxx");
} catch (MalformedURLException m) {
}
try {
urlConnection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
}
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
} catch (IOException e) {
} finally {
urlConnection.disconnect();
}
try {
JSONObject jsonObject = new JSONObject(result.toString());
JSONArray jsonArray = jsonObject.getJSONArray("rows");
JSONObject object_rows = jsonArray.getJSONObject(0);
JSONArray jsonArrayElements = object_rows.getJSONArray("elements");
JSONObject object_elements = jsonArrayElements.getJSONObject(0);
JSONObject object_duration = object_elements.getJSONObject("duration");
JSONObject object_distance = object_elements.getJSONObject("distance");
duration = object_duration.getString("text");
distance = object_distance.getString("text");
map = new HashMap<String, String>();
map.put("beachName", nameBeach);
map.put("distance", distance);
map.put("duration", duration);
map.put("latitude", latitude);
map.put("longitude", longitude);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return map;
}
}
我不太确定你想做什么,但我认为你已经把它弄得更复杂了。
据我了解,您有一个 City
对象列表,您使用它们构建一些 URL,从中检索用于构建 MarkerOptions
对象的 JSON
对象.
您可以像这样使用 AsyncTask
来做到这一点:
public class Task extends AsyncTask<City, Void, Markers> {
String currentLatitude;
String currentlongitude;
public Task(String currentLatitude, String currentlongitude){
this.currentLatitude = currentLatitude;
this.currentlongitude = currentlongitude;
}
@Override
protected String doInBackground(City... cities) {
final Markers mMap = ...;
for (City city : cities) {
GeoPoint geoPoint = city.getLocation();
String nameBeach = city.getName();
if (geoPoint != null) {
String latitude = String.valueOf(geoPoint.getLatitude());
String longitude = String.valueOf(geoPoint.getLongitude());
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
try {
URL url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxx";);
urlConnection = (HttpURLConnection) url.openConnection();
reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
JSONObject jsonObject = new JSONObject(result.toString()).getJSONArray("rows").getJSONObject(0).getJSONArray("elements").getJSONObject(0);
String duration = jsonObject.getJSONObject("duration").getString("text");
String distance = jsonObject.getJSONObject("distance").getString("text");
mMap.addMarker(new MarkerOptions().position(new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude()))
.title(nameBeach)
.snippet(distance + ", " + duration)
.icon(BitmapDescriptorFactory.defaultMarker()));
} catch (Exception e) {
e.printStackTrace();
} finally {
if(reader!=null){
try {
reader.close();
}catch (Exception e){
e.printStackTrace();
}
}
if (urlConnection != null) {
try {
urlConnection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
return mMap;
}
}
这里是你如何使用这个任务。
public class Login extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(...);
Task task = new Task(currentLatitude, currentlongitude){
@Override
protected void onPostExecute(Markers markers) {
super.onPostExecute(markers);
//This runs on the UI thread and "markers" is the "mMap" object that was create on the background thread.
}
};
List<City> cities = ....
task.execute(cities.toArray(new City[cities.size()]));
}
}
想法是您需要在 AsyncTask
的 doInBackground(...)
方法中执行所有长的 运行 操作。此外,您不需要创建其他对象来处理 AsyncTask
响应,您可以在您创建任务的 class 中覆盖任务的 onPostExecute(...)
。
我会用你最后的代码("UPDATED AFTER CHANGES"),好吗?
如果我做对了,您的 DistanceBetweenLocations 结果将是海滩地理定位数据列表。因此,在 doInBackground 中 for 循环的每次迭代中,您都在替换 "map" 变量的值,这就是您的问题。
要解决您的问题,您可以使用 HashMap 列表或 Pojo 列表,如下所示:
public class BeachPojo {
private String beachName;
private String distance;
private String duration;
private String latitude;
private String longitude;
public String getBeachName() {
return beachName;
}
public void setBeachName(String beachName) {
this.beachName = beachName;
}
public String getDistance() {
return distance;
}
public void setDistance(String distance) {
this.distance = distance;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
public String getLatitude() {
return latitude;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
}
使用 Pojo,你的 AsyncTask 将是这样的:
public class DistanceBetweenLocations extends AsyncTask<String, String, List<BeachPojo>> {
Double currentLatitude;
Double currentlongitude;
public BeachMap beachMap;
public BackendlessCollection<Beach> dataBeach;
public GoogleMap mMap;
String latitude;
String longitude;
public DistanceBetweenLocations(Double currentLatitude, Double currentlongitude){
this.currentLatitude = currentLatitude;
this.currentlongitude = currentlongitude;
}
@Override
protected List<BeachPojo> doInBackground(String... params) {
List<BeachPojo> list = new ArrayList<BeachPojo>();
BeachPojo pojo;
dataBeach = beachMap.listBeach;
for (Beach city : dataBeach.getData()) {
GeoPoint geoPoint = city.getLocation();
String nameBeach = city.getName();
if (geoPoint == null) {
} else {
latitude = String.valueOf(geoPoint.getLatitude());
longitude = String.valueOf(geoPoint.getLongitude());
HttpURLConnection urlConnection = null;
URL url = null;
StringBuilder result = null;
String duration = "";
String distance = "";
try {
url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxxx");
} catch (MalformedURLException m) {
}
try {
urlConnection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
}
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
} catch (IOException e) {
} finally {
urlConnection.disconnect();
}
try {
JSONObject jsonObject = new JSONObject(result.toString());
JSONArray jsonArray = jsonObject.getJSONArray("rows");
JSONObject object_rows = jsonArray.getJSONObject(0);
JSONArray jsonArrayElements = object_rows.getJSONArray("elements");
JSONObject object_elements = jsonArrayElements.getJSONObject(0);
JSONObject object_duration = object_elements.getJSONObject("duration");
JSONObject object_distance = object_elements.getJSONObject("distance");
duration = object_duration.getString("text");
distance = object_distance.getString("text");
pojo = new BeachPojo();
pojo.setBeachName(nameBeach);
pojo.setDistance(distance);
pojo.setDuration(duration);
pojo.setLatitude(latitude);
pojo.setLongitude(longitude);
list.add(pojo);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return list;
}
}
现在您有一个要迭代的列表。我已经为这个目标稍微调整了代码:
DistanceBetweenLocations task = new DistanceBetweenLocations(mlatituDouble, mlongitudeDouble){
@Override
protected void onPostExecute(List<BeachPojo> result) {
super.onPostExecute(result);
if (mMap == null) {
mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.mapView))
.getMap();
}
Double beachLatitude;
Double beachLongitude;
for (BeachPojo pojo : result) {
beachLatitude = Double.parseDouble(pojo.getLatitude());
beachLongitude = Double.parseDouble(pojo.getLongitude());
mMap.addMarker(new MarkerOptions().position(new LatLng(beachLatitude, beachLongitude))
.title(pojo.getBeachName())
.snippet(pojo.getDistance() + " " + pojo.getDuration())
.icon(BitmapDescriptorFactory.defaultMarker()));
}
}
};
task.execute();
我希望您理解从 AsyncTask 返回列表并在 onPostExecute 方法上循环遍历结果的想法。
注意:这是在不知道真正代码的情况下实现的,请根据实际情况进行调整。
我正在使用 google 地图来显示一些标记。标记是从数据库下载的,同时,我从 google api 获取用户当前位置与我从数据库中获取的标记之间的距离矩阵。
我的问题是我是用 .get 做的,阻塞了我的 ui(我读过 .get 阻塞了 ui:
dataFromAsyncTask = testAsyncTask.get();
现在,我试图在不阻挡 ui 的情况下做同样的事情,但我无法同时或以一种好的方式获得此标记的距离。
感谢您的帮助。
这是我的旧代码和错误代码.get:
for (City city : listCity.getData()) {
geoPoint = city.getLocation();
nameBeach = city.getName();
if (geoPoint == null) {
} else {
latitude = String.valueOf(geoPoint.getLatitude());
longitude = String.valueOf(geoPoint.getLongitude());
startRetrievenDistanceAndDuration();
try {
dataFromAsyncTask = testAsyncTask.get();
} catch (InterruptedException i) {
} catch (ExecutionException e) {
}
mMap.addMarker(new MarkerOptions().position(new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude()))
.title(nameCity)
.snippet(dataFromAsyncTask)
.icon(BitmapDescriptorFactory.defaultMarker()));
}
}
startRetrievenDistanceAndDuration 方法:
private void startRetrievenDistanceAndDuration() {
final String url;
testAsyncTask = new DistanceBetweenLocations(new FragmentCallback() {
@Override
public void onTaskDone(String result) {
}
});
url = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxx";
testAsyncTask.execute(new String[]{url});
}
public interface FragmentCallback {
public void onTaskDone(String result);
AsyncTask class:
@Override
protected String doInBackground(String... params) {
HttpURLConnection urlConnection = null;
URL url = null;
StringBuilder result = null;
String duration = "";
String distance = "";
try {
url=new URL(params[0]);
}catch (MalformedURLException m){
}
try {
urlConnection = (HttpURLConnection) url.openConnection();
}catch (IOException e){}
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
result = new StringBuilder();
String line;
while((line = reader.readLine()) != null) {
result.append(line);
}
}catch (IOException e){
} finally {
urlConnection.disconnect();
}
try {
JSONObject jsonObject = new JSONObject(result.toString());
JSONArray jsonArray = jsonObject.getJSONArray("rows");
JSONObject object_rows = jsonArray.getJSONObject(0);
JSONArray jsonArrayElements = object_rows.getJSONArray("elements");
JSONObject object_elements = jsonArrayElements.getJSONObject(0);
JSONObject object_duration = object_elements.getJSONObject("duration");
JSONObject object_distance = object_elements.getJSONObject("distance");
duration = object_duration.getString("text");
distance = object_distance.getString("text");
} catch (JSONException e) {
e.printStackTrace();
}
return distance + ", " + duration;
}
@Override
protected void onPostExecute(String result) {
mFragmentCallback.onTaskDone(result);
}
}
我正在尝试这样做,但我只显示列表的最后一个标记:
循环调用方法:
startRetrievenDistanceAndDuration();
然后在 onTaskDone 中尝试放置标记,但只得到我列表中的最后一个标记
@Override
public void onTaskDone(String result) {
mMap.addMarker(new MarkerOptions().position(new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude()))
.title(nameBeach)
.snippet(result)
.icon(BitmapDescriptorFactory.defaultMarker()));
}
更改后更新:(仍然不起作用) 我可以在 Asynctask 中解析数据并在 onPostExecute 中发送它,但我只得到一个值,而不是我拥有的 9 个值....
主要ACTIVITY:
DistanceBetweenLocations task = new DistanceBetweenLocations(mlatituDouble, mlongitudeDouble){
@Override
protected void onPostExecute(HashMap<String, String> result) {
super.onPostExecute(result);
String name = result.get("beachName");
String distance = result.get("distance");
String duration = result.get("duration");
String latitue = result.get("latitude");
String longitude = result.get("longitude");
Double mlatituDouble = Double.parseDouble(latitue);
Double mlongitudeDouble = Double.parseDouble(longitude);
if (mMap == null) {
mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.mapView))
.getMap();
Toast.makeText(getActivity(), "mMap NO null", Toast.LENGTH_SHORT).show();
mMap.addMarker(new MarkerOptions().position(new LatLng(mlatituDouble, mlongitudeDouble))
.title(name)
.snippet(distance + " " + duration)
.icon(BitmapDescriptorFactory.defaultMarker()));
}
}
};
task.execute();
异步任务CLASS:.
public class DistanceBetweenLocations extends AsyncTask<String, String, HashMap<String, String>> {
Double currentLatitude;
Double currentlongitude;
public BeachMap beachMap;
public BackendlessCollection<Beach> dataBeach;
public GoogleMap mMap;
String latitude;
String longitude;
HashMap<String, String> map;
public DistanceBetweenLocations(Double currentLatitude, Double currentlongitude){
this.currentLatitude = currentLatitude;
this.currentlongitude = currentlongitude;
}
@Override
protected HashMap<String, String> doInBackground(String... params) {
dataBeach = beachMap.listBeach;
for (Beach city : dataBeach.getData()) {
GeoPoint geoPoint = city.getLocation();
String nameBeach = city.getName();
if (geoPoint == null) {
} else {
latitude = String.valueOf(geoPoint.getLatitude());
longitude = String.valueOf(geoPoint.getLongitude());
HttpURLConnection urlConnection = null;
URL url = null;
StringBuilder result = null;
String duration = "";
String distance = "";
try {
url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxxx");
} catch (MalformedURLException m) {
}
try {
urlConnection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
}
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
} catch (IOException e) {
} finally {
urlConnection.disconnect();
}
try {
JSONObject jsonObject = new JSONObject(result.toString());
JSONArray jsonArray = jsonObject.getJSONArray("rows");
JSONObject object_rows = jsonArray.getJSONObject(0);
JSONArray jsonArrayElements = object_rows.getJSONArray("elements");
JSONObject object_elements = jsonArrayElements.getJSONObject(0);
JSONObject object_duration = object_elements.getJSONObject("duration");
JSONObject object_distance = object_elements.getJSONObject("distance");
duration = object_duration.getString("text");
distance = object_distance.getString("text");
map = new HashMap<String, String>();
map.put("beachName", nameBeach);
map.put("distance", distance);
map.put("duration", duration);
map.put("latitude", latitude);
map.put("longitude", longitude);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return map;
}
}
我不太确定你想做什么,但我认为你已经把它弄得更复杂了。
据我了解,您有一个 City
对象列表,您使用它们构建一些 URL,从中检索用于构建 MarkerOptions
对象的 JSON
对象.
您可以像这样使用 AsyncTask
来做到这一点:
public class Task extends AsyncTask<City, Void, Markers> {
String currentLatitude;
String currentlongitude;
public Task(String currentLatitude, String currentlongitude){
this.currentLatitude = currentLatitude;
this.currentlongitude = currentlongitude;
}
@Override
protected String doInBackground(City... cities) {
final Markers mMap = ...;
for (City city : cities) {
GeoPoint geoPoint = city.getLocation();
String nameBeach = city.getName();
if (geoPoint != null) {
String latitude = String.valueOf(geoPoint.getLatitude());
String longitude = String.valueOf(geoPoint.getLongitude());
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
try {
URL url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxx";);
urlConnection = (HttpURLConnection) url.openConnection();
reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
JSONObject jsonObject = new JSONObject(result.toString()).getJSONArray("rows").getJSONObject(0).getJSONArray("elements").getJSONObject(0);
String duration = jsonObject.getJSONObject("duration").getString("text");
String distance = jsonObject.getJSONObject("distance").getString("text");
mMap.addMarker(new MarkerOptions().position(new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude()))
.title(nameBeach)
.snippet(distance + ", " + duration)
.icon(BitmapDescriptorFactory.defaultMarker()));
} catch (Exception e) {
e.printStackTrace();
} finally {
if(reader!=null){
try {
reader.close();
}catch (Exception e){
e.printStackTrace();
}
}
if (urlConnection != null) {
try {
urlConnection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
return mMap;
}
}
这里是你如何使用这个任务。
public class Login extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(...);
Task task = new Task(currentLatitude, currentlongitude){
@Override
protected void onPostExecute(Markers markers) {
super.onPostExecute(markers);
//This runs on the UI thread and "markers" is the "mMap" object that was create on the background thread.
}
};
List<City> cities = ....
task.execute(cities.toArray(new City[cities.size()]));
}
}
想法是您需要在 AsyncTask
的 doInBackground(...)
方法中执行所有长的 运行 操作。此外,您不需要创建其他对象来处理 AsyncTask
响应,您可以在您创建任务的 class 中覆盖任务的 onPostExecute(...)
。
我会用你最后的代码("UPDATED AFTER CHANGES"),好吗?
如果我做对了,您的 DistanceBetweenLocations 结果将是海滩地理定位数据列表。因此,在 doInBackground 中 for 循环的每次迭代中,您都在替换 "map" 变量的值,这就是您的问题。
要解决您的问题,您可以使用 HashMap 列表或 Pojo 列表,如下所示:
public class BeachPojo {
private String beachName;
private String distance;
private String duration;
private String latitude;
private String longitude;
public String getBeachName() {
return beachName;
}
public void setBeachName(String beachName) {
this.beachName = beachName;
}
public String getDistance() {
return distance;
}
public void setDistance(String distance) {
this.distance = distance;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
public String getLatitude() {
return latitude;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
}
使用 Pojo,你的 AsyncTask 将是这样的:
public class DistanceBetweenLocations extends AsyncTask<String, String, List<BeachPojo>> {
Double currentLatitude;
Double currentlongitude;
public BeachMap beachMap;
public BackendlessCollection<Beach> dataBeach;
public GoogleMap mMap;
String latitude;
String longitude;
public DistanceBetweenLocations(Double currentLatitude, Double currentlongitude){
this.currentLatitude = currentLatitude;
this.currentlongitude = currentlongitude;
}
@Override
protected List<BeachPojo> doInBackground(String... params) {
List<BeachPojo> list = new ArrayList<BeachPojo>();
BeachPojo pojo;
dataBeach = beachMap.listBeach;
for (Beach city : dataBeach.getData()) {
GeoPoint geoPoint = city.getLocation();
String nameBeach = city.getName();
if (geoPoint == null) {
} else {
latitude = String.valueOf(geoPoint.getLatitude());
longitude = String.valueOf(geoPoint.getLongitude());
HttpURLConnection urlConnection = null;
URL url = null;
StringBuilder result = null;
String duration = "";
String distance = "";
try {
url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxxx");
} catch (MalformedURLException m) {
}
try {
urlConnection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
}
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
} catch (IOException e) {
} finally {
urlConnection.disconnect();
}
try {
JSONObject jsonObject = new JSONObject(result.toString());
JSONArray jsonArray = jsonObject.getJSONArray("rows");
JSONObject object_rows = jsonArray.getJSONObject(0);
JSONArray jsonArrayElements = object_rows.getJSONArray("elements");
JSONObject object_elements = jsonArrayElements.getJSONObject(0);
JSONObject object_duration = object_elements.getJSONObject("duration");
JSONObject object_distance = object_elements.getJSONObject("distance");
duration = object_duration.getString("text");
distance = object_distance.getString("text");
pojo = new BeachPojo();
pojo.setBeachName(nameBeach);
pojo.setDistance(distance);
pojo.setDuration(duration);
pojo.setLatitude(latitude);
pojo.setLongitude(longitude);
list.add(pojo);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return list;
}
}
现在您有一个要迭代的列表。我已经为这个目标稍微调整了代码:
DistanceBetweenLocations task = new DistanceBetweenLocations(mlatituDouble, mlongitudeDouble){
@Override
protected void onPostExecute(List<BeachPojo> result) {
super.onPostExecute(result);
if (mMap == null) {
mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.mapView))
.getMap();
}
Double beachLatitude;
Double beachLongitude;
for (BeachPojo pojo : result) {
beachLatitude = Double.parseDouble(pojo.getLatitude());
beachLongitude = Double.parseDouble(pojo.getLongitude());
mMap.addMarker(new MarkerOptions().position(new LatLng(beachLatitude, beachLongitude))
.title(pojo.getBeachName())
.snippet(pojo.getDistance() + " " + pojo.getDuration())
.icon(BitmapDescriptorFactory.defaultMarker()));
}
}
};
task.execute();
我希望您理解从 AsyncTask 返回列表并在 onPostExecute 方法上循环遍历结果的想法。
注意:这是在不知道真正代码的情况下实现的,请根据实际情况进行调整。