2012-03-15 16 views
4

我尝试在单击按钮时将Toast消息从线程发送到UIThread。 但是,每次单击按钮时都不会出现Toast。 我正在使用处理程序来执行此操作。从单独的线程发出Toast消息

这是一个完整的代码,如果我做的地方重大失误:

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; 
} 
} 

预先感谢您!

编辑:在后台线程

toastHandler.post(toastRunnable); 

:通过使用此解决它:

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

在UIThread这。

回答

4

试试这个:

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

你的面包需要在UI线程来完成。以下是如何做到这一点:

注意:ClassName.this是必要的,因为this本身将指您的匿名Runnable类。

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

我只想添加*为什么*这是必需的:除非是“主”线程(通常称为GUI线程),否则不能从另一个线程访问GUI。该方法将吐司消息方法推送到GUI线程上,因此可以显示它。 – 2012-03-15 23:13:31