Search code examples
androidgoogle-mapsgoogle-maps-markersgoogle-geocoder

App stops responding on multiple geocoder requests


The app stops responding for a while and then come back to normal with all the markers. The app hangs even for a list with size 30. Here is my code,

private void addMarkersByPlace(List<JSONObject> data_arr){
    try {
        for (int i = 0; i < data_arr.size(); i++) {
            List<Address> addresses = geoCoder.getFromLocationName(data_arr.get(i).getString("position"), 1);
            if (addresses.size() > 0) {
                LatLng position = new LatLng(addresses.get(0).getLatitude()+(Math.random()/200),addresses.get(0).getLongitude()+(Math.random()/200));
                Bitmap bmImg = Ion.with(this).load(data_arr.get(i).getString("icon")).asBitmap().get();
                mMap.addMarker(new MarkerOptions()
                        .position(position)
                        .title(data_arr.get(i).getString("title"))
                        .snippet(data_arr.get(i).getString("snippet"))
                        .icon(BitmapDescriptorFactory.fromBitmap(bmImg))
                );
            }
        }
        progress.dismiss();
    }
    catch (Exception e){
        txt_msg.setText("ERROR : "+ e.toString());
    }
}

Any help would be appreciated.


Solution

  • Your main thread does too much work, and this may cause an ANR.

    Create an AsyncTask (documentation) that queries the geocoder and draw the Markers on the onPostExecute method (the markers must be drawn on the main thread).

    Your AsyncTask can be like this (not tested):

    private class QueryGeocoder extends AsyncTask<List<JSONObject>, Integer, List<Address>> {
        @Override
        protected List<Address> doInBackground(List<JSONObject>... objects) {
            List<Address> addresses = new ArrayList<>();
    
            try {
                for (JSONObject object : objects) {
                    addresses.add(geoCoder.getFromLocationName(object.getString("position"), 1));
                }
            }
            catch (Exception e){
            }
    
            return addresses;
        }
    
        protected void onPostExecute(List<Address> result) {
            for (Address address : result) {
                LatLng position = new LatLng(address.getLatitude()+(Math.random()/200),address.getLongitude()+(Math.random()/200));
                Bitmap bmImg = Ion.with(this).load(address.getString("icon")).asBitmap().get();
                mMap.addMarker(new MarkerOptions()
                                .position(position)
                                .title(address.getString("title"))
                                .snippet(address.getString("snippet"))
                                .icon(BitmapDescriptorFactory.fromBitmap(bmImg))
                );                
            }
        }
    }
    

    You can execute it like this:

    new QueryGeocoder().execute(data_arr);