【问题标题】:Execution order in AsyncTask inside loop循环内 AsyncTask 中的执行顺序
【发布时间】:2014-09-26 20:41:41
【问题描述】:

我有一个关于执行顺序的问题。我从服务器(城市名称,LatLng)和 onPostExecute 获取一些数据,我正在尝试计算城市之间的距离。在最后一次 onPostExecute 期间,有一些距离计算。问题是在

for(j=0;j<3;j++) {          

            or = markerPoints.get(j);
            dest = markerPoints.get(j+1);

            Log.d("or", or.toString());
            Log.d("dest", dest.toString());

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

            }

在for循环完成后第一次执行downloadTask,即j等于2时。为什么不是3次;是不是很奇怪;

我的整个代码

 public class Check_Itineraries1 extends FragmentActivity {

    private ProgressDialog pDialog;
    String username , origin_lat ,origin_lng ,destination_lat ,destination_lng ,
    waypoint1_lat ,waypoint1_lng ,waypoint2_lat ,waypoint2_lng ,waypoints ,
    origin_lat_pro ,origin_lng_pro ,destination_lat_pro ,destination_lng_pro , start_pro , final_pro;
    int i, j ,b ;
    double x,z ,t ,s;
    TextView v1 , v2;

    ArrayList<Double> Array = new ArrayList<Double>();
    ArrayList<Double> Array_add = new ArrayList<Double>();
    ArrayList<Double> Array_dif = new ArrayList<Double>();
    ListView list;
    ArrayList<LatLng> markerPoints;
    // URL to get contacts JSON
    private static String LOGIN_URL = "http://**************************";

    public static final String PREFS_NAME = "MyPreferencesFile";

    // JSON Node names

    JSONParser jsonParser = new JSONParser();



    // contacts JSONArray
    JSONArray contacts = null;

    // Hashmap for ListView
    ArrayList<HashMap<String, String>> itinList , final_itinList ;




    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.checkitineraries);

        itinList = new ArrayList<HashMap<String, String>>();

        new GetData().execute();
    }

    private class GetData extends AsyncTask<Void, Void, Void> {

        public void onPreExecute() {
            super.onPreExecute();
            Log.d("meg", "meg");

            pDialog = new ProgressDialog(Check_Itineraries1.this);
            pDialog.setMessage("Επεξεργάζομαι τα δεδομένα...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();

            SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
            username = settings.getString("username", "nikos");

        }

        protected Void doInBackground(Void... args) {
            // TODO Auto-generated method stub

            try {

                // Building Parameters
                List<NameValuePair> params = new ArrayList<NameValuePair>();
                params.add(new BasicNameValuePair("username", username));

                JSONObject json = jsonParser.makeHttpRequest(LOGIN_URL, "POST",
                        params);

                // JSONObject jObj = new JSONObject();
                JSONArray itin_results = json.getJSONArray("itin_results");

                for (int i = 0; i < itin_results.length(); i++) {
                    JSONObject c = itin_results.getJSONObject(i);

                    String username = c.getString("username");
                    String startPoliPro = c.getString("startPoliPro");
                    String start_lat_pro = c.getString("start_lat_pro");
                    String start_lng_pro = c.getString("start_lng_pro");
                    String finalPoliPro = c.getString("finalPoliPro");
                    String final_lat_pro = c.getString("final_lat_pro");
                    String final_lng_pro = c.getString("final_lng_pro");

                    LinkedHashMap<String, String> pinakas = new LinkedHashMap<String, String>();

                    // adding each child node to HashMap key => value
                    pinakas.put("username", username);
                    pinakas.put("startPoliPro", startPoliPro);
                    pinakas.put("start_lat_pro", start_lat_pro);
                    pinakas.put("start_lng_pro", start_lng_pro);
                    pinakas.put("finalPoliPro", finalPoliPro);
                    pinakas.put("final_lat_pro", final_lat_pro);
                    pinakas.put("final_lng_pro", final_lng_pro);

                    // Διαλέγω αφετηρία και προορισμό του δρομολογίου του επαγγελματία


                    Log.d("1", username);
                    Log.d("2", startPoliPro);
                    Log.d("3", start_lat_pro);
                    Log.d("4", start_lng_pro);
                    Log.d("5", finalPoliPro);
                    Log.d("6", final_lat_pro);
                    Log.d("7", final_lng_pro);


                    itinList.add(pinakas);
                    b = itin_results.length();  // Είναι τα δρομολόγια των πελατων που ταιριάζουν ΣΥΝ το δρομολόγιο του επαγγελματία
                    Log.d("b", String.valueOf(b));



                }
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            // Dismiss the progress dialog
            if (pDialog.isShowing())
                pDialog.dismiss();


            origin_lat_pro = itinList.get(0).get("start_lat_pro").toString();
            origin_lng_pro = itinList.get(0).get("start_lng_pro").toString();   
            destination_lat_pro = itinList.get(0).get("final_lat_pro").toString();
            destination_lng_pro = itinList.get(0).get("final_lng_pro").toString();

            start_pro = itinList.get(0).get("startPoliPro").toString();
            final_pro = itinList.get(0).get("finalPoliPro").toString();

            LatLng origin_pro = new LatLng(Double.parseDouble(origin_lat_pro),Double.parseDouble(origin_lng_pro));
            LatLng destination_pro = new LatLng(Double.parseDouble(destination_lat_pro),Double.parseDouble(destination_lng_pro));

            for (i = 0; i <b; i++) {    

            markerPoints = new ArrayList<LatLng>();

            origin_lat = itinList.get(i).get("start_lat_pro").toString();
            origin_lng = itinList.get(i).get("start_lng_pro").toString();   
            destination_lat = itinList.get(i).get("final_lat_pro").toString();
            destination_lng = itinList.get(i).get("final_lng_pro").toString();

            LatLng or = new LatLng(Double.parseDouble(origin_lat),Double.parseDouble(origin_lng));
            LatLng dest = new LatLng(Double.parseDouble(destination_lat),Double.parseDouble(destination_lng));

            markerPoints.add(origin_pro);
            markerPoints.add(or);
            markerPoints.add(dest);
            markerPoints.add(destination_pro);

            Log.d("a", markerPoints.get(0).toString());
            Log.d("b", markerPoints.get(1).toString());
            Log.d("c", markerPoints.get(2).toString());
            Log.d("d", markerPoints.get(3).toString());

            z = 0;  

            for(j=0;j<3;j++) {          

            or = markerPoints.get(j);
            dest = markerPoints.get(j+1);

            Log.d("or", or.toString());
            Log.d("dest", dest.toString());

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

            }
            }           
                }
                }

    //Αυτοτελές
    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";

        Log.d("sos1", "sos1");
        // Building the parameters to the web service
        String parameters = str_origin + "&" + str_dest + "&" + sensor;


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

            Log.d("sos2", "sos2");

            // 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;
    }

    //Αυτοτελές//

    // Fetches data from url passed

    //Αυτοτελές
    private class DownloadTask extends AsyncTask<String, Void, String> {

        // Downloading data in non-ui thread
        @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]);
                Log.d("sos3", "sos3");
            } catch (Exception e) {
                Log.d("Background Task", e.toString());
            }
            return data;
        }

        // Executes in UI thread, after the execution of
        // doInBackground()
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);

            ParserTask parserTask = new ParserTask();

            Log.d("sos4", "sos4");
            // Invokes the thread for parsing the JSON data
            parserTask.execute(result);

        }
    }

    //Αυτοτελές//

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

// Parsing the data in non-ui thread
@Override
protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {

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

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

        Log.d("sos5", "sos5");
        // Starts parsing data
        routes = parser.parse(jObject);

        Log.d("json", jObject.toString());
    } catch (Exception e) {
        e.printStackTrace();
    }
    return routes;
}

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


protected void onPostExecute(List<List<HashMap<String, String>>> result) {
    ArrayList<LatLng> points = null;
    String distance = "";
    String duration = "";

    Log.d("sos6", "sos6");
    Log.d("result", String.valueOf(result.size()));

    // Traversing through all the routes
    for (int i = 0; i < result.size(); i++) {
        points = new ArrayList<LatLng>();

        // Fetching i-th route
        List<HashMap<String, String>> path = result.get(i);

        // Fetching all the points in i-th route
        for(int j=0;j<path.size();j++){
            HashMap<String,String> point = path.get(j); 

            if(j==0){    // Get distance from the list
                distance = point.get("distance");
                continue;
            }else if(j==1){ // Get duration from the list
                duration = point.get("duration");
                continue;
            }   

        double lat = Double.parseDouble(point.get("lat"));
            double lng = Double.parseDouble(point.get("lng"));
            LatLng position = new LatLng(lat, lng);

            points.add(position);
            //

            //
        }

    }

    Log.d("finito", distance);

    String asd[] = distance.split(" ");
    Log.d("ass", asd[0]);
    Log.d("ass", asd[1]);

    double x = Double.parseDouble(asd[0]);
    if(asd[1].equals("m")){
         x = x/1000;        
    }
    Log.d("intValue", String.valueOf(x));

    x = Math.round(x);


    Array.add(x);

    Log.d("Array", Array.toString());
    if(Array.size()==3){
        z = Array.get(0) + Array.get(1) + Array.get(2);
        Array_add.add(z);
        Array.clear();
    }

    Log.d("size", String.valueOf(Array_add.size()));

        Log.d("Αθροισμα", String.valueOf(z));

}


}
    //Αυτοτελές

}

【问题讨论】:

  • 再说一遍,这就是Async 的意思。
  • 不敢相信AsyncTask是随机调用...一定有逻辑解释
  • 是的。有一个执行器,它在一个线程上运行异步任务。 (所有这些都在文档中详细说明)通常,从 android 4 开始,所有 asynctask 都有 1 个线程,这意味着它们按调用的顺序依次调用 execute
  • 这不能回答我的问题:为什么在循环完成后调用 downloadTask
  • 没有。构造函数和 onPreExecute 将立即被调用。但 doInBackground 可能在循环结束后。 '被调用'到底是什么意思?

标签: android


【解决方案1】:

Android Developers 说:

在首次引入时,AsyncTask 是在单个 后台线程。从...开始 {android.os.Build.VERSION_CODES#DONUT},这里改成了游泳池 允许多个任务并行运行的线程。开始 使用{ android.os.Build.VERSION_CODES#HONEYCOMB},执行任务 在单个线程上以避免常见的应用程序错误 并行执行。

此外,由于AsyncTask 的执行者是静态的,因此您将获得应用程序的单个执行者。

现在它已经在运行 GetData asyncTask 并且它连续运行 asyncsTask 所以它不能执行你的DownloadTask。 GetDataTask 完成后才能运行。

如果你想并行运行多个 asynctask,可以查看Asynctask.executeOnExecutor()

【讨论】:

  • 你对我的案子有什么建议?我想使用许多 asyncTask 保持严格的执行顺序来避免 NullPointerExceptions
  • 我认为您的用例不需要多个 aysntask。基本上你只能在 GetData 任务的 doinBackground 中执行 DownloadTask 和 ParserTask 的代码。
  • 感谢您的回复。我看到很多帖子建议在第一个 AsyncTask 的 onPostExecute 中嵌入第二个 AsyncTask。根据您的回答,它不会每次都失败吗?
  • 可以使用executeonexecute,但需要自己管理同步
猜你喜欢
  • 1970-01-01
  • 2020-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多