我开发Android应用程序,现在我有问题。下面是我的代码的一部分,它一直在跳过" for"部分。当我在for语句中放置一个断点时,它会在该点停止,并且很好地执行这些行并生成我想要的输出。当我只是跑步时#39;应用程序,它跳过那部分,以及#34;字符串位置"价值不会改变。我用谷歌搜索,有人说它与线程相关的问题。所以我把同步化的方法,仍然没有工作。还有其他建议吗?
我试图显示仅与问题相关的代码,但我认为现在显示整体对于那些试图提供帮助的人来说更有用,这是我在showMapActivity上的整个代码。你可以看到我尝试了一些方法,没有任何效果。将路径的信息保存到String url中是我遇到问题的地方。我测试了,其他部分似乎工作正常。我知道我的代码非常庞大,这就是为什么我只发布部分代码。 TMap相关类从.jar文件导入。
public class showMapActivity extends Activity {
TMapData tmapdata=new TMapData();
TMapView tmapView;
TMapPoint origin, dest;
volatile ArrayList<TMapPoint> points=new ArrayList<>();
private TextView x;
private TextView y;
private HashMap<String,LatLng> coordinates;
private HashMap<LatLng,Double> finalpoint;
static private ConcurrentHashMap<Double,Double> path;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_map);
coordinates=new HashMap<>();
Intent intent=getIntent();
tmapView=new TMapView(this);
path=new ConcurrentHashMap<>();
coordinates=(HashMap<String,LatLng>)intent.getSerializableExtra("coordinate");
path=getPathPoints(coordinates);
int i=0;
String url=getUrl();
//String url = "https://maps.googleapis.com/maps/api/elevation/json?locations=";
//String locations="";
/*
Iterator<Double> keys= path.keySet().iterator();
while(keys.hasNext()){
Double key=keys.next();
//String lat=String.valueOf(key);
//String lng=String.valueOf(path.get(key));
locations=locations+String.valueOf(key)+","+String.valueOf(path.get(key));
if(keys.hasNext())
locations=locations+"|";
}path.entrySet()
*/
/*
for(ConcurrentHashMap.Entry<Double,Double> elem : path.entrySet())
{
String lat=String.valueOf(elem.getKey());
String lng=String.valueOf(elem.getValue());
locations=locations+lat+","+lng;
i++;
if(i!=path.size())
{
locations=locations+"|";
}
}
*/
//url=url+locations+"&key=AIzaSyDD88VFMPIfC5sr0XsFL0PDCE-QRN8gQto";
//String url=getUrl(path);
FetchUrl fetchUrl=new FetchUrl();
fetchUrl.execute(url);
}
private ConcurrentHashMap<Double,Double> getPathPoints(HashMap<String,LatLng> coordinates)
{
final ConcurrentHashMap<Double,Double> Path=new ConcurrentHashMap<>();
tmapView.setSKPMapApiKey("6bb5b7f3-1274-3c5e-ba93-790aee876673");
origin=new TMapPoint(coordinates.get("origin").latitude,coordinates.get("origin").longitude);
dest=new TMapPoint(coordinates.get("dest").latitude,coordinates.get("dest").longitude);
tmapdata.findPathData(origin, dest, new TMapData.FindPathDataListenerCallback() {
@Override
public void onFindPathData(TMapPolyLine polyLine) {
points=polyLine.getLinePoint();
for(TMapPoint point : points )
Path.put(point.getLatitude(),point.getLongitude());
}
});
return Path;
}
//ConcurrentHashMap<Double,Double> path
private synchronized String getUrl() {
int i=0;
String url = "https://maps.googleapis.com/maps/api/elevation/json?locations=";
String locations="";
for(HashMap.Entry<Double,Double> elem : path.entrySet())
{
String lat=String.valueOf(elem.getKey());
String lng=String.valueOf(elem.getValue());
locations=locations+lat+","+lng;
i++;
if(i!=path.size())
{
locations=locations+"|";
}
}
url=url+locations+"&key=AIzaSyDD88VFMPIfC5sr0XsFL0PDCE-QRN8gQto";
//https://maps.googleapis.com/maps/api/elevation/json?locations=
// 39.7391536,-104.9847034|36.455556,-116.866667&key=AIzaSyDD88VFMPIfC5sr0XsFL0PDCE-QRN8gQto
// Output format
return url;
}
private class FetchUrl extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... url) {
// For storing data from web service
String data = "";
try {
// Fetching the data from web service
//downloadURL
data = downloadUrl(url[0]);
Log.d("Background Task data", data.toString());
} catch (Exception e) {
Log.d("Background Task", e.toString());
}
return data;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//ParserTask
ParserTask parserTask = new ParserTask();
// Invokes the thread for parsing the JSON data
parserTask.execute(result);
}
}
private String downloadUrl(String strUrl) throws IOException {
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
urlConnection = (HttpURLConnection) url.openConnection();
// Connecting to url
urlConnection.connect();
//읽은 데이터를 버퍼에 저장
// Reading data from url
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
Log.d("downloadUrl", data.toString());
br.close();
} catch (Exception e) {
Log.d("Exception", e.toString());
} finally {
iStream.close();
urlConnection.disconnect();
}
return data;
}
private class ParserTask extends AsyncTask<String, Integer, ArrayList<Double>> {
// Parsing the data in non-ui thread
@Override
protected ArrayList<Double> doInBackground(String... jsonData) {
JSONObject jObject;
ArrayList<Double> altitude = null;
try {
jObject = new JSONObject(jsonData[0]);
Log.d("ParserTask",jsonData[0].toString());
//DataParser class 호출
DataParser parser = new DataParser();
Log.d("ParserTask", parser.toString());
// Starts parsing data
altitude = parser.parse(jObject);
Log.d("ParserTask","Getting Altitudes");
Log.d("ParserTask",altitude.toString());
} catch (Exception e) {
Log.d("ParserTask",e.toString());
e.printStackTrace();
}
return altitude;
}
// Executes in UI thread, after the parsing process
@Override
protected void onPostExecute(ArrayList<Double> result) {
finalpoint=new HashMap<>();
LatLng latLng;
int i=0;
for(HashMap.Entry<Double,Double> elem : path.entrySet() )
{
latLng=new LatLng(elem.getKey(),elem.getValue());
finalpoint.put(latLng,result.get(i++));
}
x = (TextView) findViewById(R.id.textView5);
y = (TextView) findViewById(R.id.textView6);
x.setText(String.valueOf(finalpoint.get(coordinates.get("origin"))));
y.setText(String.valueOf(finalpoint.get(coordinates.get("dest"))));
}
}
}
答案 0 :(得分:0)
(将此作为答案发表道歉 - 我还没有发表评论所需的声誉)
简单地将synchronized
添加到方法中并不一定能保证线程安全。
如何以及何时填充path
?
提供其他信息后更新
问题似乎是路径点是异步生成的,并且您试图在生成过程完成之前(或者甚至可能已经开始)使用它们。发生这种情况是因为findPathData
只是启动生成过程并立即返回(即在生成过程完成之前)。在您的代码中,然后继续构建应该立即包含点数据的URL。此时,背景点生成过程可能尚未完成,甚至可能尚未开始。因此,积分图可能为空或不完整,并且您的网址不会按预期生成。
在创建URL之前,您需要找到一种等待异步处理返回所有路径点数据的方法。对于您正在使用的findPathData
方法的版本,这似乎非常困难,如果不是不可能的话,因为它一次通过回调返回点,您可能不知道将生成多少点。
我快速浏览了TMapData的API,它有一个findPathDataAll
方法,它似乎生成了所有的点,并在一个回调调用中返回它们,而不是一个接一个。如果确实如此(抱歉,我无法读取韩语),您可以使用此方法然后从回调中生成URL,因为当它被调用时,您知道生成过程已经完成。如果您这样做,请务必确保在与UI或活动进行交互之前进入主线程。
希望有所帮助。