Dusan Dimitrijevic
Dusan Dimitrijevic

Reputation: 3219

Algorithm for calculating distance between two location is taking too much

Firstly, i'm fetching some data from server database and getting some addresses which i'm reversing to location latitude and longitude, so i can calculate after that distance between my location latlng and theirs.

But for some reason Activity freezes at loading data and list is loading very slow with this feature. This is how i'm calculating distance between two location:

AndroidNetworking.get(AppConfig.GET_FIELDS_ORDER_BY_CITY.replace("city", tvCurrentLocation.getText().toString()))
            .setPriority(Priority.IMMEDIATE)
            .build().getAsJSONObject(new JSONObjectRequestListener() {
        @Override
        public void onResponse(JSONObject response) {
            mFieldList.clear();
            try {
                if (!response.getBoolean("error")) {
                    JSONArray fieldsArray = response.getJSONArray("fields");
                    for (int i = 0; i < fieldsArray.length(); i++) {
                        JSONObject fieldObj = fieldsArray.getJSONObject(i);
                        Field field = new Field();
                        ...
                        field.setCertificate(fieldObj.getString("certificate"));

                        Log.d("Location", fieldObj.getString("address"));

                        // If i delete from here  
                        if (!fieldObj.getString("address").isEmpty()) {
                            LatLng latLng = AppUtils.getLocationFromAddress(SearchActivityV2.this,
                                    fieldObj.getString("address"));

                            float dist = AppUtils.distFrom(44.8029925f, 20.495337f, (float) latLng.latitude, (float) latLng.longitude);
                            DecimalFormat df = new DecimalFormat("####0.0");
                            if (dist > 1000) {
                                double distance = AppUtils.calculationByDistance(new LatLng(44.8029925, 20.495337), latLng);
                                field.setDistance(df.format(distance) + " km");
                            } else {
                                String newValue = Double.toString(Math.floor(dist));
                                field.setDistance(newValue + " m");
                            }
                        } else {
                            field.setDistance("1000");
                        }
                        mFieldList.add(field);
                    }
                    // to here, list would load immediately, so
                    // something is not right with this
                    mFieldsListAdapter.notifyDataSetChanged();
                }
            } catch (JSONException e) {
                Log.e(getClass().getSimpleName(), e.getMessage());
                e.printStackTrace();
            }
        }

        @Override
        public void onError(ANError anError) {
            Log.e(getClass().getSimpleName(), anError.getMessage());
        }
    });ield.setDistance(df.format(distance) + " km");
                            } else {
                                String newValue = Double.toString(Math.floor(dist));
                                field.setDistance(newValue + " m");
                            }

Any suggestions or tips what should i do? Thank you!

Upvotes: 0

Views: 100

Answers (1)

Roman Pozdnyakov
Roman Pozdnyakov

Reputation: 408

"onResponse" method works on main thread, So data parsing and heavy calculations may freeze app's UI thread. Try to move all your parsing code and calculations to AsyncTask's "doInBackground" and update your adapter in "onPostExecute" because you must be on ui thread to perform this action.

code example:

    private class ResponseParser extends AsyncTask<JSONObject, Void, Void> {

    @Override
    protected Void doInBackground(JSONObject... params) throws JSONException {
        mFieldList.clear();
        JSONArray fieldsArr = params[0].getJSONArray("fields");
        if (!response.getBoolean("error")) {
            JSONArray fieldsArray = response.getJSONArray("fields");
            for (int i = 0; i < fieldsArray.length(); i++) {
                JSONObject fieldObj = fieldsArray.getJSONObject(i);
                Field field = new Field();
                ...
                field.setCertificate(fieldObj.getString("certificate"));

                Log.d("Location", fieldObj.getString("address"));

                // If i delete from here
                if (!fieldObj.getString("address").isEmpty()) {
                    LatLng latLng = AppUtils.getLocationFromAddress(SearchActivityV2.this,
                            fieldObj.getString("address"));

                    float dist = AppUtils.distFrom(44.8029925f, 20.495337f, (float) latLng.latitude, (float) latLng.longitude);
                    DecimalFormat df = new DecimalFormat("####0.0");
                    if (dist > 1000) {
                        double distance = AppUtils.calculationByDistance(new LatLng(44.8029925, 20.495337), latLng);
                        field.setDistance(df.format(distance) + " km");
                    } else {
                        String newValue = Double.toString(Math.floor(dist));
                        field.setDistance(newValue + " m");
                    }
                } else {
                    field.setDistance("1000");
                }
                mFieldList.add(field);
            }
            // to here, list would load immediately, so
            // something is not right with this
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        mFieldsListAdapter.notifyDataSetChanged();
    }
}

Hope it helps!

Upvotes: 1

Related Questions