"对于" loop在AsyncTask执行之前获取所有值

时间:2015-01-16 12:45:04

标签: android

如您所见,下面的代码尝试连接到Google API并计算城市之间的距离。我把AsyncTask放在“for”循环中。最后,我尝试将“diff”值放在数组的末尾。 请忽略代码的目的,对我要求的内容无关紧要。 我的问题:似乎第一个“for”循环中的“w”int在执行 DownloadTask类之前将所有值都取为“b”。因此,“itinList1.get(w).put(”diff“,String.valueOf(0));”接近结束的行值b 一次而不是值0,1,... b如预期的那样我得到了 Logcat中的“IndexOutOfBoundsException”消息。 提前谢谢。

for (w = 0; w < b; w++) {
                markerPoints = new ArrayList<LatLng>();

                Log.d("w1", String.valueOf(w));

                if(itinList1.get(w).get("username").equals(username)){

                    origin_lat = itinnList1.get(w).get("start_lat_pro").toString();
                    origin_lng = itinList1.get(w).get("start_lng_pro").toString();
                    destination_lat = itinList1.get(w).get("final_lat_pro").toString();
                    destination_lng = itinList1.get(w).get("final_lng_pro").toString();                 


                for(w1=w+1;w1<b;w1++){

                    if(!username.equals(itinList1.get(w1).get("username"))){



                waypoint1_lat = itinList1.get(w1).get("start_lat_pro").toString();
                waypoint1_lng = itinList1.get(w1).get("start_lng_pro").toString();
                waypoint2_lat = itinList1.get(w1).get("final_lat_pro").toString();
                waypoint2_lng = itinList1.get(w1).get("final_lng_pro").toString();

                LatLng origin1 = new LatLng(Double.parseDouble(origin_lat),
                        Double.parseDouble(origin_lng));
                LatLng destination = new LatLng(
                        Double.parseDouble(destination_lat),
                        Double.parseDouble(destination_lng));
                LatLng waypoint1 = new LatLng(
                        Double.parseDouble(waypoint1_lat),
                        Double.parseDouble(waypoint1_lng));
                LatLng waypoint2 = new LatLng(
                        Double.parseDouble(waypoint2_lat),
                        Double.parseDouble(waypoint2_lng));

                markerPoints.add(origin1);
                markerPoints.add(destination);
                markerPoints.add(waypoint1);
                markerPoints.add(waypoint2);

                LatLng or = markerPoints.get(0);
                LatLng dest = markerPoints.get(1);



                // Getting URL to the Google Directions API
                String url = getDirectionsUrl(or, dest);

                DownloadTask downloadTask = new DownloadTask();

                // Start downloading json data from Google Directions API
                downloadTask.execute(url);


            } else {

                break;
            }
        }
                }
            }
        }

        private String getDirectionsUrl(LatLng or, LatLng dest) {

            // Origin of route
            String str_origin = "origin=" + or.latitude + "," + or.longitude;

            // Destination of route
            String str_dest = "destination=" + dest.latitude + ","
                    + dest.longitude;

            // Sensor enabled
            String sensor = "sensor=false";

            // Waypoints
            LatLng way1 = markerPoints.get(2);
            LatLng way2 = markerPoints.get(3);


            // Waypoints
            waypoints = "";
            for (int i = 2; i < markerPoints.size(); i++) {
                LatLng point = (LatLng) markerPoints.get(i);
                if (i == 2)
                    waypoints = "waypoints=";

                waypoints += point.latitude + "," + point.longitude + "|";

            }

            // Building the parameters to the web service
            String parameters = str_origin + "&" + str_dest + "&" + sensor
                    + "&" + waypoints;

            // Output format
            String output = "json";

            // Building the url to the web service
            String url = "https://maps.googleapis.com/maps/api/directions/"
                    + output + "?" + parameters;

            return url;
        }

        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();

                br.close();

            } catch (Exception e) {
                Log.d("Exception while downloading url", e.toString());
            } finally {
                iStream.close();
                urlConnection.disconnect();
            }
            return data;
        }


        private class DownloadTask 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
                    data = downloadUrl(url[0]);
                } catch (Exception e) {
                    Log.d("Background Task", e.toString());
                }
                return data;
            }


            @Override
            protected void onPostExecute(String result) {
                super.onPostExecute(result);


                ParserTask parserTask = new ParserTask();

                // Invokes the thread for parsing the JSON data
                parserTask.execute(result);

            }
        }


        public class ParserTask extends
                AsyncTask<String, Integer, ArrayList<HashMap<String, String>>> {

            @Override
            public void onPreExecute() {
                super.onPreExecute();               

            }

            @Override
            protected ArrayList<HashMap<String, String>> doInBackground(
                    String... jsonData) {

                JSONObject jObject;
                List<List<HashMap<String, String>>> routes = null;

                try {
                    jObject = new JSONObject(jsonData[0]);
                    DirectionsJSONParser1 parser = new DirectionsJSONParser1();

                    // Starts parsing data
                    routes = parser.parse(jObject);

                    JSONArray routeObject = jObject.getJSONArray("routes");
                    JSONObject first = routeObject.getJSONObject(0);
                    JSONArray legs = first.getJSONArray("legs");

                    z = 0;

                    for (i = 0; i < legs.length(); i++) {
                        JSONObject legs1 = legs.getJSONObject(i);
                        JSONObject distanceObject = legs1.getJSONObject("distance");
                        String distance = distanceObject.getString("text");

                        String asd[] = distance.split(" ");


                        double x = Double.parseDouble(asd[0]);
                        if (asd[1].equals("m")) {
                            x = x / 1000;

                        }
                        x = Math.round(x);
                        z = z + x;

                    }

                    sum.add(z); 



                    if (sum.size() < 2) {
                        q = 0;
                    **//here is the problem..**  
 itinList1.get(w).put("diff", String.valueOf(0)); 
                    } else {
                        q = z - sum.get(w);
                        if (q < 0) {
                            q = 0;
                        }
                        itinList1.get(sum.size() - 1).put("diff",
                                String.valueOf(q));

                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }

                Log.d("q", String.valueOf(q));              

                return itinList1;
            }

            // Executes in UI thread, after the parsing process
            @Override

            protected void onPostExecute(
                    ArrayList<HashMap<String, String>> result) {
....rest of code....

1 个答案:

答案 0 :(得分:2)

此代码

for (w = 0; w < b; w++) {
    ...
    new DownloadTask().execute(url);
}

这将异步启动所有下载任务,因此for循环可能会在任何任务开始之前完成。因此,他们都看到w的最后一个值。

您需要做的是将w作为参数传递给任务,就像您已经传入URL一样。您可以为该

创建一个新类
public class DownloadParams {
    public String Url;
    public int W;
}

然后你的下载任务如下:

private class DownloadTask extends AsyncTask<DownloadParams, Void, String> {

并使用所有参数执行它:

DownloadParams params = new DownloadParams();
params.Url = url;
params.W = w;
new DownloadTask().execute(params);