从单独的线程发出Toast消息

时间:2012-03-15 23:02:53

标签: java android multithreading handler toast

单击按钮时,我尝试从线程向UIThread发送Toast消息。 但是,每次单击按钮时,Toast都不会出现。 我正在使用Handler来做这件事。

这是完整的代码,以防我在某处犯了一个重大错误:

package google.map.activity;

//imports

public class GoogleMapActivity extends MapActivity {

int lat = 0;
int lng = 0;
Location location;

MapController mc;
GeoPoint p;
private MapController mapController;
private MapView mapView;
private LocationManager locationManager;

// ////////////////////////////////////////////////////////////////////////////////////////////////////////

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.googlemapactivity);

    mapView = (MapView) findViewById(R.id.mapView);
    mapView.setBuiltInZoomControls(false);
    mapView.setSatellite(false);
    mapController = mapView.getController();
    mapController.setZoom(19);

    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5,
            0, new GeoUpdateHandler());

    locationManager.requestLocationUpdates(
            LocationManager.NETWORK_PROVIDER, 5, 0, new GeoUpdateHandler());

    // //////---Switch to
    // Start/////////////////////////////////////////////////////////////////////////////

    Button switchToMain = (Button) findViewById(R.id.switchtomain);
    switchToMain.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View view) {
            final Intent intent = new Intent();
            setResult(RESULT_OK, intent);
            finish();
        }
    });

    // ////--Call a
    // Cab/////////////////////////////////////////////////////////////////////////////////////

    Button getCab = (Button) findViewById(R.id.GetCab); // create the Button

    final Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);

    getCab.setOnClickListener(new View.OnClickListener() {

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

        Location locationTest = locationManager
                .getLastKnownLocation(bestProvider); // get

        // last
        // known

        // location fix from
        // locationManager

        public void getAddress() {

            String msg = null;

            Looper.prepare();

            if (locationTest == null) {

                bestProvider = LocationManager.NETWORK_PROVIDER;

            }

            Location location = locationManager
                    .getLastKnownLocation(bestProvider);

            Geocoder geocoder = new Geocoder(getBaseContext(), Locale
                    .getDefault());// create
            // new
            // GeoCoder

            String result = null; // initialize result

            try { // try to get Address list from location of bestProvider
                List<Address> list = geocoder.getFromLocation(
                        location.getLatitude(), location.getLongitude(), 1);
                if (list != null && list.size() > 0) {
                    Address address = list.get(0);
                    // sending back first address line and locality
                    result = address.getAddressLine(0) + ", "
                            + address.getLocality();// set result
                    // to
                    // Streetname+Nr.
                    // and City
                }
            } catch (IOException e) {
                msg = String.format("IOException!!");

            } finally {

                if (result != null) {

                    msg = String.format(result);

                    // Looper.loop();

                } else
                    msg = String.format("Keine Position");
            }
            Message myMessage = new Message();
            Bundle resBundle = new Bundle();
            resBundle.putString("status", msg);
            myMessage.obj = resBundle;
            handler.sendMessage(myMessage);

        }

        @Override
        public void onClick(View v) {

            new Thread(new Runnable() {
                public void run() {

                    // Looper.myLooper();
                    // Looper.prepare();

                    getAddress(); // get the Address

                    Location locationTest = locationManager
                            .getLastKnownLocation(bestProvider);

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

                    Location location2 = locationManager
                            .getLastKnownLocation(bestProvider);

                    int lat = (int) (location2.getLatitude() * 1E6); // get
                    // position
                    // for GeoPoint
                    int lng = (int) (location2.getLongitude() * 1E6);

                    GeoPoint point = new GeoPoint(lat, lng); // create
                    // GeoPoint
                    // for
                    // mapController
                    mapController.animateTo(point);

                }

            }).start();

            // toast.show();

        }
    });

}

public Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        Toast.makeText(getApplicationContext(), msg.toString(),
                Toast.LENGTH_LONG);
    }
};

public class GeoUpdateHandler implements LocationListener {

    @Override
    public void onLocationChanged(Location location) {
        int lat = (int) (location.getLatitude() * 1E6);
        int lng = (int) (location.getLongitude() * 1E6);

        GeoPoint point = new GeoPoint(lat, lng);
        mapController.animateTo(point); // mapController.setCenter(point);

    }

    @Override
    public void onProviderDisabled(String provider) {
    }

    @Override
    public void onProviderEnabled(String provider) {
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }

}

@Override
protected boolean isRouteDisplayed() {
    // TODO Auto-generated method stub
    return false;
}
}

提前谢谢!

编辑:使用此解决方法:

Handler toastHandler = new Handler();
Runnable toastRunnable = new Runnable() {public void run() {Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();}};

在UIThread和this:

toastHandler.post(toastRunnable);

在后台线程中。

2 个答案:

答案 0 :(得分:4)

试试这个:

runOnUiThread(new Runnable()
{
    public void run()
    {
        // Here you can make a Toast
    }
});

答案 1 :(得分:3)

您的Toast需要在UI线程中完成。以下是如何做到这一点:

注意:ClassName.this是必需的,因为this本身会引用您的匿名Runnable类。

runOnUiThread(new Runnable() {
  @Override
  public void run()
  {
    Toast.makeText(ClassName.this, R.string.something, Toast.LENGTH_LONG).show();
  }
});