GeoCoder AsyncTask不会在后台更新TextView

时间:2012-05-03 15:12:28

标签: android android-asynctask geocoding android-maps

情景:

所以我到目前为止所做的是创建一个AsyncTask来处理我的GeoCoder,它每3分钟更新一次(用于测试目的)。然后我设置了一个TimerTask,用于显示每4分钟用户当前地址的Toast消息。 (TimerTasks不包含在代码中)

所以这是问题所在:

当我在我的应用程序中时,一切都很好,但是当我的应用程序在后台运行时,Toast消息会在我退出应用程序之前停留在应用程序最后设置的任何地址。我确信AsyncTask确实在后台运行(Checked LogCats),看起来好像一切都在后台运行,我只是不能在Toast上显示当前地址。

所有的想法和意见将不胜感激!

这是我的代码:

 public class statuspage extends MapActivity {

LocationManager locationManager;
MapView mapView;
Criteria criteria;
Location location;
Geocoder gc;
Address address;

String bestProvider;
String LOCATION_SERVICE = "location";
String addressString = "Searching for Nearest Address";
StringBuilder sb;

private MapController mapController;
private MyLocationOverlay myLocation;

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

    // Get Mapping Controllers etc //
    mapView = (MapView) findViewById(R.id.mapView);
    mapController = mapView.getController();
    mapController.setZoom(17);
    mapView.setBuiltInZoomControls(true);

    // Add the MyLocationOverlay //
    myLocation = new MyLocationOverlay(this, mapView);
    mapView.getOverlays().add(myLocation);
    myLocation.enableCompass();
    myLocation.enableMyLocation();

    // Animates the map to GPS Position //
    myLocation.runOnFirstFix(new Runnable() {
        @Override
        public void run() {
            mapController.animateTo(myLocation.getMyLocation());

        }
    });
}

@Override
protected boolean isRouteDisplayed() {

    // Location Manager Intiation
    locationManager = (LocationManager) statuspage.this
            .getSystemService(LOCATION_SERVICE);
    criteria = new Criteria();

    // More accurate, GPS fix.
    criteria.setAccuracy(Criteria.ACCURACY_FINE); // More accurate, GPS fix.
    bestProvider = locationManager.getBestProvider(criteria, true);

    location = locationManager.getLastKnownLocation(bestProvider);
    updateWithNewLocation(location);

    locationManager.requestLocationUpdates(bestProvider, 60000, 10,
            locationListener); // 1800000 = 30 Min

    return false;
}

class GeoCoder extends AsyncTask<Void, Void, Void> {

    String lat = "Acquiring";
    String lng = "Acquiring";

    @Override
    protected Void doInBackground(Void... params) {
        if (location != null) {

            /**
             * double latitude = myLocation.getMyLocation().getLatitudeE6();
             * double longitude =
             * myLocation.getMyLocation().getLongitudeE6();
             */

            double latitude = location.getLatitude();
            double longitude = location.getLongitude();

            lat = "" + latitude;
            lng = "" + longitude;

            // gc = new Geocoder(statuspage.this, Locale.getDefault());
            Geocoder gc = new Geocoder(getApplicationContext(),
                    Locale.getDefault());
            try {

                List<Address> addresses = gc.getFromLocation(latitude,
                        longitude, 1);

                sb = new StringBuilder();
                if (addresses != null && addresses.size() > 0) {
                    address = addresses.get(0);

                    int noOfMaxAddressLine = address
                            .getMaxAddressLineIndex();
                    if (noOfMaxAddressLine > 0) {
                        for (int i = 0; i < address
                                .getMaxAddressLineIndex(); i++) {
                            sb.append(address.getAddressLine(i)).append(
                                    "\n");
                        }
                        addressString = sb.toString();

                    }
                }
            } catch (Exception e) {

                addressString = "Sorry, we are trying to find information about this location";
            }

        }
        return null;
    }


    @Override
    protected void onPostExecute(Void result) {
        TextView scrollview = (TextView) findViewById(R.id.scrollview);

        // Latitude and Longitude TextView
        TextView etlongitude = (TextView) findViewById(R.id.etlongitude);
        TextView etlatitude = (TextView) findViewById(R.id.etlatitude);

        // TextView to display GeoCoder Address
        scrollview.setGravity(Gravity.CENTER);
        scrollview.setText("Your location:" + "\n"
                + "(Accurate to 500 meters)" + "\n" + (addressString));

        Log.d("Address", (addressString));

        // Latitude and Longitude TextView Display Coordinates //
        etlongitude.setText(lng);
        etlatitude.setText(lat);

        // Log.d("GeoCoder", "In-Task");

        return;
    }

2 个答案:

答案 0 :(得分:0)

当您使用assync任务时,您无法在后台更新UI。无法从后台内部线程连接UI。连接UI的唯一方法是使用onPostExecute()。并使用此onPostExecute ()函数更新UI.try从后台发送消息,并通过检查消息在postexecute上执行UI内容。这将帮助您确定。

答案 1 :(得分:0)

我遇到了同样的问题。如果我保持当前活动,没问题,但如果我在doInBackgroud运行时离开活动,onPostExecute将退出Toast行。

要解决此问题,您必须使用处理程序:
在课堂上

private static final int TOAST  = 0;
private Handler mHandler = null;

OnCreate()

// Creation of the handler to display Toasts
if (mHandler == null) {
    mHandler = new Handler() {
        @Override
        public void handleMessage(Message _msg) {
            switch (_msg.what) {
            case TOAST:
            Toast.makeText(ServerTabHost.this, (String)_msg.obj, Toast.LENGTH_LONG).show();
            break;
            default : break;
        }
        super.handleMessage(_msg);
        }
    };
}

onPostExecute()

Message msg = new Message();
msg.what = TOAST;
msg.obj = "my toast message";
mHandler.sendMessage(msg);

在您的代码中,它看起来像这样:

public class statuspage extends MapActivity {

// These two lines are for the handler
private static final int TOAST  = 0;
private Handler mHandler = null;

LocationManager locationManager;
MapView mapView;
Criteria criteria;
Location location;
Geocoder gc;
Address address;

String bestProvider;
String LOCATION_SERVICE = "location";
String addressString = "Searching for Nearest Address";
StringBuilder sb;

private MapController mapController;
private MyLocationOverlay myLocation;

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

    // Get Mapping Controllers etc //
    mapView = (MapView) findViewById(R.id.mapView);
    mapController = mapView.getController();
    mapController.setZoom(17);
    mapView.setBuiltInZoomControls(true);

    // Add the MyLocationOverlay //
    myLocation = new MyLocationOverlay(this, mapView);
    mapView.getOverlays().add(myLocation);
    myLocation.enableCompass();
    myLocation.enableMyLocation();

    // Animates the map to GPS Position //
    myLocation.runOnFirstFix(new Runnable() {
        @Override
        public void run() {
            mapController.animateTo(myLocation.getMyLocation());

        }
    });

    // Creation of the handler to display Toasts
    if (mHandler == null) {
        mHandler = new Handler() {
        @Override
        public void handleMessage(Message _msg) {
            switch (_msg.what) {
                case TOAST:
                Toast.makeText(ServerTabHost.this, (String)_msg.obj, Toast.LENGTH_LONG).show();
                break;
                default : break;
            }
            super.handleMessage(_msg);
            }
        };
    }
}

@Override
protected boolean isRouteDisplayed() {

    // Location Manager Intiation
    locationManager = (LocationManager) statuspage.this
            .getSystemService(LOCATION_SERVICE);
    criteria = new Criteria();

    // More accurate, GPS fix.
    criteria.setAccuracy(Criteria.ACCURACY_FINE); // More accurate, GPS fix.
    bestProvider = locationManager.getBestProvider(criteria, true);

    location = locationManager.getLastKnownLocation(bestProvider);
    updateWithNewLocation(location);

    locationManager.requestLocationUpdates(bestProvider, 60000, 10,
            locationListener); // 1800000 = 30 Min

    return false;
}

class GeoCoder extends AsyncTask<Void, Void, Void> {

    String lat = "Acquiring";
    String lng = "Acquiring";

    @Override
    protected Void doInBackground(Void... params) {
        if (location != null) {

            /**
             * double latitude = myLocation.getMyLocation().getLatitudeE6();
             * double longitude =
             * myLocation.getMyLocation().getLongitudeE6();
             */

            double latitude = location.getLatitude();
            double longitude = location.getLongitude();

            lat = "" + latitude;
            lng = "" + longitude;

            // gc = new Geocoder(statuspage.this, Locale.getDefault());
            Geocoder gc = new Geocoder(getApplicationContext(),
                    Locale.getDefault());
            try {

                List<Address> addresses = gc.getFromLocation(latitude,
                        longitude, 1);

                sb = new StringBuilder();
                if (addresses != null && addresses.size() > 0) {
                    address = addresses.get(0);

                    int noOfMaxAddressLine = address
                            .getMaxAddressLineIndex();
                    if (noOfMaxAddressLine > 0) {
                        for (int i = 0; i < address
                                .getMaxAddressLineIndex(); i++) {
                            sb.append(address.getAddressLine(i)).append(
                                    "\n");
                        }
                        addressString = sb.toString();

                    }
                }
            } catch (Exception e) {

                addressString = "Sorry, we are trying to find information about this location";
            }

        }
        return null;
    }


    @Override
    protected void onPostExecute(Void result) {

        // Sending the Toast message through the handler
        Message msg = new Message();
    msg.what = TOAST;
    msg.obj = "My toast message";
    mHandler.sendMessage(msg);

        TextView scrollview = (TextView) findViewById(R.id.scrollview);

        // Latitude and Longitude TextView
        TextView etlongitude = (TextView) findViewById(R.id.etlongitude);
        TextView etlatitude = (TextView) findViewById(R.id.etlatitude);

        // TextView to display GeoCoder Address
        scrollview.setGravity(Gravity.CENTER);
        scrollview.setText("Your location:" + "\n"
                + "(Accurate to 500 meters)" + "\n" + (addressString));

        Log.d("Address", (addressString));

        // Latitude and Longitude TextView Display Coordinates //
        etlongitude.setText(lng);
        etlatitude.setText(lat);

        // Log.d("GeoCoder", "In-Task");

        return;
    }

就个人而言,我在片段中,所以我不得不在主机活动中创建处理程序,然后在片段构造函数中传递它。