使用 AsyncTask 与 distancematrix 和 google Maps 阻止了我的 UI [英] My UI is blocked using AsyncTask with distancematrix and google Maps

本文介绍了使用 AsyncTask 与 distancematrix 和 google Maps 阻止了我的 UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用谷歌地图来显示一些标记.标记是从数据库中下载的,同时,我从 google api 中获取了用户当前位置和我从数据库中获取的标记之间的距离矩阵.

I'm using google maps to show some markers. The markers are download from a database and, at the same time, I get the distancematrix from google api, between the current position of the user and the marker that I get from the database.

我的问题是我使用 .get 执行此操作,阻塞了我的 ui(我读过 .get 阻塞了 ui:

My problem is that I was doing this with .get, bloking my ui (I've read that .get blocked the ui:

dataFromAsyncTask = testAsyncTask.get();

现在,我正在尝试在不阻塞用户界面的情况下执行相同操作,但是我无法同时或以一种好的方式获得此标记的距离.

Now, I'm trying to do the same without blocking the ui, but I'm not be able to get at the same time, or in a good way, the distance for this markers.

感谢您的帮助.

这是我的旧代码和错误的 .get 代码:

This is my code with my old and wrong .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 方法:

startRetrievenDistanceAndDuration method:

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 类:

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

我正在尝试这样做,但我只显示列表的最后一个标记:

I'm trying to do this, but I only show the last marker of my list:

在循环中调用方法:

startRetrievenDistanceAndDuration();

在 onTaskDone 中尝试放置标记,但只获取我列表中的最后一个标记

And in onTaskDone try to put the marker, but only get the last marker of my list

@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 个值....

UPDATED AFTER CHANGES: (still don't work) I can parse the data in Asynctask and send it in onPostExecute, but I only get one value, and not the 9 values that I have....

主要活动:

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

异步任务类:.

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

}

推荐答案

我会使用你上次的代码(UPDATED AFTER CHANGES"),好吗?

I'll use your last code (the "UPDATED AFTER CHANGES"), ok?

如果我猜对了,您的 DistanceBetweenLocations 结果将是海滩地理位置数据列表.因此,在 doInBackground 中 for 循环的每次迭代中,您都在替换map"变量的值,这是您的问题.

If I get it right, your DistanceBetweenLocations result will be a list of beaches geolocation data. So, on every iteration of the for loop in doInBackground, you are replacing the value of "map" variable, this is your problem.

要解决您的问题,您可以使用 HashMap 列表或 Pojo 列表,如下所示:

To solve your problem, you can have a List of HashMap or a List of a Pojo like this:

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 将如下所示:

Using the Pojo, your AsyncTask will be like this:

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

现在您有一个要迭代的列表.我已经根据这个目标稍微调整了代码:

Now you have a List to iterate. I have adjusted the code a little bit to this goal:

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 返回一个 List 并在 onPostExecute 方法上循环遍历结果的想法.

I hope you understand the idea of returning a List from your AsyncTask and loop throught the result on onPostExecute method.

注意:这是一个不知道真正代码的实现,然后你应该适应你的现实.

Note: this is an implementation without knowing the real code, then you should adjust to your reality.

这篇关于使用 AsyncTask 与 distancematrix 和 google Maps 阻止了我的 UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆