我有一个班负责处理与Google地图相关的所有事情
下面的代码是这个类的一个片段;在这个片段(processPaths方法)中我做了一个foreach来读取整个Marker列表,其中每次迭代我创建一个Path对象和两个实现Runnable的对象。其中一个对象是PathProducer,负责挂载JSON请求,获取响应,解码并返回LatLng列表;另一个将获取PathProducer创建的latLng列表,并将通知MapsActivity根据此列表添加折线。 Path对象由两个Runnable对象共享(这就是我锁定/同步此对象的原因,PathConsumer无法通知MapsActivity在PathProducer计算它之前绘制Path)。
public void processPaths(){
int count = 1;
for (Marker m : markerList) {
Path path = new Path(from, m.getPosition());
PathProducer producer = new PathProducer("Producer " + count, path);
PathConsumer consumer = new PathConsumer("Consumer " + count, path);
producer.run();
consumer.run();
count++;
}
}
以下是我的Path,PathProducer和PathConsumer类
路径:
package com.trackit.app.utilities;
import android.util.Log;
import com.google.android.gms.maps.model.LatLng;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Shanx on 19/09/2016.
*/
public class Path{
private static final String TAG = Path.class.getSimpleName();
private LatLng from;
private LatLng to;
private List<LatLng> waypoint = new ArrayList<LatLng>();
private boolean created = false;
public Path(LatLng from, LatLng to){
this.from = from;
this.to = to;
Log.e(TAG, "Path going from " + from + " to " + to + " created.");
}
public LatLng getFrom(){
return from;
}
public LatLng getTo(){
return to;
}
public boolean wasCreated(){
return created;
}
public List<LatLng> getWaypoint(){
return waypoint;
}
public void setWaypoint(List<LatLng> path){
waypoint = path;
}
public void created(boolean path){
created = path;
}
}
PathProducer:
package com.trackit.app.utilities;
import android.app.ProgressDialog;
import android.widget.Toast;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.android.gms.maps.model.LatLng;
import com.google.maps.android.SphericalUtil;
import com.trackit.app.track_it_v002.MapsActivity;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Created by Shanx on 16/09/2016.
*/
public class PathProducer implements Runnable {
private String name;
private String trackingMode = "walking";
private Path path;
public PathProducer(String name, Path path){
this.name = name;
this.path = path;
}
@Override
public void run() {
findPath();
}
private String createRequestURL(LatLng from, LatLng to){
return "https://maps.googleapis.com/maps/api/directions/json?origin=" + Double.toString
(from.latitude) + "," + Double.toString( from.longitude) + "&destination=" +
Double.toString(to.latitude) + "," + Double.toString(to.longitude) +
"&sensor=false&mode=" + trackingMode + "&alternatives=true&" +
"key=< my personal key =) >";
}
public void findPath(){
//Getting the URL
String url = createRequestURL(path.getFrom(), path.getTo());
//Showing a dialog till we get the route
final ProgressDialog loading = ProgressDialog.show(MapsActivity.mActivity, "Getting Route",
"Please wait...", false, false);
//Creating a string request
StringRequest stringRequest = new StringRequest(url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
loading.dismiss();
//Calling the method drawPath to draw the path
drawPath(response);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
loading.dismiss();
}
});
//Adding the request to request queue
RequestQueue requestQueue = Volley.newRequestQueue(MapsActivity.mActivity);
requestQueue.add(stringRequest);
}
//The parameter is the server response
private void drawPath(String result) {
//Calculating the distance in meters
Double distance = SphericalUtil.computeDistanceBetween(path.getFrom(), path.getTo());
//Displaying the distance
Toast.makeText(MapsActivity.mActivity, String.valueOf(distance + " Meters"), Toast.
LENGTH_LONG).show();
try {
//Parsing json
final JSONObject json = new JSONObject(result);
JSONArray routeArray = json.getJSONArray("routes");
JSONObject routes = routeArray.getJSONObject(0);
JSONObject overviewPolylines = routes.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
path.setWaypoint(PolylineEncoder.decodeA(encodedString));
path.created(true);
this.notify();
}
catch (JSONException e) {
}
}
public String getName(){
return name;
}
}
PathConsumer:
package com.trackit.app.utilities;
import android.graphics.Color;
import com.google.android.gms.maps.model.PolylineOptions;
import com.trackit.app.track_it_v002.MapsActivity;
/**
* Created by Shanx on 20/09/2016.
*/
public class PathConsumer implements Runnable {
private String name;
private Path path;
public PathConsumer(String name, Path path){
this.name = name;
this.path = path;
}
@Override
public void run() {
synchronized (path) {
while(!path.wasCreated()) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
MapsActivity.mActivity.getMap().addPolyline(new PolylineOptions()
.addAll(path.getWaypoint())
.width(10)
.color(Color.GREEN)
.geodesic(true)
.clickable(true)
);
}
public String getName(){
return name;
}
}
触发按钮OnClick后调用processPaths方法;这是在我在GoogleMap对象中添加一些标记后发生的。
问题是,在地图中添加一些标记并调用processPaths()后,应用程序会冻结。我不熟悉Java中的多线程,但是我做了一些研究,我在这里读了一些帖子,但没有人能帮助我......
你们可以指出我的错误是什么?当我的朋友都没有使用特定的编程语言= S
时,StackOverflow总是我最后的选择