adding AsyncTask for searching location

2020-08-01 08:48发布

问题:

so I am making an application to get current position. The code below is working fine

String stringAddress = "";

public void getLocation(View view){
    final LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);

    Criteria kriteria = new Criteria();
    kriteria.setAccuracy(Criteria.ACCURACY_FINE);
    kriteria.setAltitudeRequired(false);
    kriteria.setBearingRequired(false);
    kriteria.setCostAllowed(true);
    kriteria.setPowerRequirement(Criteria.POWER_LOW);
    final String provider = lm.getBestProvider(kriteria, true);

    final Location lokasi = lm.getLastKnownLocation(provider);
    updateWithNewLocation(lokasi);
    lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 5, ll);

    edittext_position.setText(stringAddress);
}

private void updateWithNewLocation(Location 
    if(lokasi != null){
        double lat = lokasi.getLatitude();
        double lng = lokasi.getLongitude();
        Geocoder gc = new Geocoder(this, Locale.getDefault());

        try{
            List addresses = gc.getFromLocation(lat, lng, 1);
            StringBuilder sb = new StringBuilder();

            if(addresses.size()>0){
                Address address = addresses.get(0);
                sb.append(address.getAddressLine(0));
                stringAddress= sb.toString();
            }

        } catch (Exception e){

        }
    }
}

private final LocationListener ll = new LocationListener() {
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    public void onProviderEnabled(String provider) {

    }

    public void onProviderDisabled(String provider) {
        updateWithNewLocation(null);
    }

    public void onLocationChanged(Location location) {
        updateWithNewLocation(location);
    }
}

but the problem is everytime I call getLocation() function, the application hang for a couple second before returning the result. I know to solve this problem using aSyncTask but I don't know how to start. Appreciate your help.

Thank you

回答1:

It's snippet from my application:

public void getCurrentLocation(final ListenerGetCurrentLocation listenerGetCurrentLocation) {
    new AsyncTask<Void, Void, List<Address>>() {

        @Override
        protected List<Address> doInBackground(Void... voids) {
            Geocoder geo = new Geocoder(instance);

            List<Address> listAddresses = null;

            Criteria criteria = new Criteria();
            String bestProvider = locationManager.getBestProvider(criteria, true);

            if (bestProvider == null) {
                bestProvider = LocationManager.NETWORK_PROVIDER;
            }

            Location location = locationManager.getLastKnownLocation(bestProvider);

            try {
                if (location != null) {
                    listAddresses = geo.getFromLocation(location.getLatitude(), 
                                                        location.getLongitude(), 
                                                        1);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            return listAddresses;
        }

        public void onPostExecute(List<Address> listAddresses) {                
            Address _address = null;
            if ((listAddresses != null) && (listAddresses.size() > 0)) {
                _address = listAddresses.get(0);

                GeoPoint currentPosition = new GeoPoint(((int)(_address.getLatitude() * 1E6)), 
                                                        ((int)(_address.getLongitude() * 1E6)));
            }

        }

    }.execute();
}


回答2:

requestLocationUpdates() is asynchronous, it doesn't block your app. It polls the location in the background, then it calls the listener.

However, gc.getFromLocation() is not. This is probably the cause of your lag

Create a new AsyncTask, Eclipse will propose you to override those methods

@Override
protected List<String> doInBackground(String... params) {
   // this is done in the background so it won't block the UI. The return type must be set to List<String> (I think default is just String)
   return gc.getFromLocation()
}


@Override
protected void onPostExecute(List<String> adresses) {
    // called when the GC work is finished. You can now use your list of addresses and display them
}

Don't forget to call execute() on your task.