2012-04-12 3 views
0

Кто-нибудь знает, почему AsyncTask продолжает сбой? В основном в моем приложении, я хотел бы получить координаты GPS и настроить его на мою позицию в mapview. Затем я хотел бы использовать GeoCode для отображения текущего адреса моей позиции.AsyncTask Crashing App

Прежде чем я начал экспериментировать с AsyncTask, приложение отображало все отлично, (показывает текущую позицию на карте и сообщает мне, какой адрес я ближайший, и отображает его в текстовом виде), однако он был очень медленным и лагированным, потому что я didnt реализовать AsyncTask. Теперь, когда я реализовал AsyncTask, это дает мне ошибки. Может ли кто-нибудь помочь?

Heres мой код:

public class statuspage extends MapActivity { 

private MapController mapController; 
private MyLocationOverlay myLocation; 
Location location; 


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

    new MapOverlay().execute(); 

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

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

     public void run() { 
      mapController.animateTo(myLocation.getMyLocation()); 

     } 
    }); 
} 



class MapOverlay extends AsyncTask<Void,Long,DataPackage> { 


    @Override 
    protected DataPackage doInBackground(Void... arg0) { 
     return new DataPackage(); 
    } 
} 

class DataPackage { 

    public String addressString = null; 
    double latitude = location.getLatitude(); 
    double longitude = location.getLongitude(); 

    public DataPackage(addressString, latitude, longitude) { 
     statuspage.this.addressString = addressString; 
     statuspage.this.latitude = location.getLatitude(); 
     statuspage.this.longitude = location.getLongitude(); 

    } 
} 


protected boolean isRouteDisplayed() { 

    // Location Manager Intiation 
    LocationManager locationManager; 
    String bestProvider; 
    String LOCATION_SERVICE = "location"; 
    locationManager = (LocationManager) statuspage.this 
      .getSystemService(LOCATION_SERVICE); 
    Criteria 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); 
    if (location != null) { 

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

     // Disables longitude textview Keyboard Popup. 
     //InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
     //imm.hideSoftInputFromWindow(etlongitude.getWindowToken(), 0); 

     // Disables latitude textview Keyboard Popup. 
     //InputMethodManager imm2 = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
     //imm2.hideSoftInputFromWindow(etlatitude.getWindowToken(), 0); 



     // Latitude and Longitude TextView Display Coordinates 
     etlongitude.setText("Longitude:" + "\n" + (longitude)); 
     /** longitude textview */ 
     etlatitude.setText("Latitude:" + "\n" + (latitude)); 
     /** latitude textview */ 

     addressString = "No address found"; 

     Geocoder gc = new Geocoder(statuspage.this, Locale.getDefault()); 
     try { 
      List<Address> addresses = gc.getFromLocation(latitude, 
        longitude, 1); 
      StringBuilder sb = new StringBuilder(); 
      if (addresses.size() > 0) { 
       Address address = addresses.get(0); 

       for (int i = 0; i < address.getMaxAddressLineIndex(); i++) 


       sb.append(address.getAddressLine(i)).append("\n"); 
       //sb.append(address.getFeatureName()).append("\n"); 
       //sb.append(address.getPhone()).append("\n"); 
       //sb.append(address.getLocality()).append("\n"); 
       //sb.append(address.getPostalCode()).append("\n"); 
       //sb.append(address.getCountryName()); 
      } 
      addressString = sb.toString(); 


      TextView scrollview = (TextView) findViewById(R.id.scrollview); 
      scrollview.setText("Your location:" + "\n" + "(Accurate to 500 meters)" +"\n" +(addressString)); 

     } catch (IOException e) { 
     } 

     // locationManager.removeUpdates((LocationListener) location); 
     locationManager = null; 

    } else { 

    } 

    return false; 
} 



protected void onResume() { 
    myLocation.enableMyLocation(); 
} 

protected void onPause() { 
    myLocation.disableMyLocation(); 
} 

public void onBackPressed() { 

    // Button OnClick Vibrating Service 
    Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 

    // Vibrate Service 
    vib.vibrate(50); 

    startActivity(new Intent(statuspage.this, AgentPortalActivity.class)); 
    statuspage.this.finish(); 

    /** Fading Transition Effect */ 
    overridePendingTransition(R.anim.fadein, R.anim.fadeout); 

    return; 

} 
} 

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

} 
} 

Вот мои журналы:

04-12 09:14:15.682: W/dalvikvm(13103): threadid=11: thread exiting with uncaught exception (group=0x40015578) 
04-12 09:14:15.686: E/AndroidRuntime(13103): FATAL EXCEPTION: AsyncTask #1 
04-12 09:14:15.686: E/AndroidRuntime(13103): java.lang.RuntimeException: An error occured while executing doInBackground() 
04-12 09:14:15.686: E/AndroidRuntime(13103): at android.os.AsyncTask$3.done(AsyncTask.java:200) 
04-12 09:14:15.686: E/AndroidRuntime(13103): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
04-12 09:14:15.686: E/AndroidRuntime(13103): at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
04-12 09:14:15.686: E/AndroidRuntime(13103): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
04-12 09:14:15.686: E/AndroidRuntime(13103): at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
04-12 09:14:15.686: E/AndroidRuntime(13103): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
04-12 09:14:15.686: E/AndroidRuntime(13103): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
04-12 09:14:15.686: E/AndroidRuntime(13103): at java.lang.Thread.run(Thread.java:1019) 
04-12 09:14:15.686: E/AndroidRuntime(13103): Caused by: java.lang.NullPointerException 
04-12 09:14:15.686: E/AndroidRuntime(13103): at com.jetdelivery.mobile.statuspage$MapOverlay.doInBackground(statuspage.java:119) 
04-12 09:14:15.686: E/AndroidRuntime(13103): at com.jetdelivery.mobile.statuspage$MapOverlay.doInBackground(statuspage.java:1) 
04-12 09:14:15.686: E/AndroidRuntime(13103): at android.os.AsyncTask$2.call(AsyncTask.java:185) 
04-12 09:14:15.686: E/AndroidRuntime(13103): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
04-12 09:14:15.686: E/AndroidRuntime(13103): ... 4 more 

Спасибо, ребята.

ответ

1

Ваш код разбивает ваше приложение, потому что вы пытаетесь получить доступ к элементам управления в потоке пользовательского интерфейса без обработчика и в неправильной области выполнения.

Вы должны прочитать на AsyncTask и как правильно обрабатывать взаимодействие с пользовательским интерфейсом. На этой странице есть очень хорошая информация.

Чтобы обновить пользовательский интерфейс, вы должны реализовать onPostExecute(), который обеспечивает результат от doInBackground() и работает в потоке пользовательского интерфейса, так что вы можете безопасно обновить пользовательский интерфейс.

Соответствующий код ломка в вашем который должен быть перемещен в onPostExecute():

  // Latitude and Longitude TextView Display Coordinates 
      etlongitude.setText("Longitude:" + "\n" + (longitude)); 
      /** longitude textview */ 
      etlatitude.setText("Latitude:" + "\n" + (latitude)); 
      /** latitude textview */ 


      TextView scrollview = (TextView) findViewById(R.id.scrollview); 
      scrollview.setText("Your location:" + "\n" 
        + "(Accurate to 500 meters)" + "\n" + (addressString)); 

Редактировать: Добавлен пример из комментариев обсуждения.

class DataPackage { 
    public String Address = null; 
    public double Latitude = 0.0; 
    public double Longitude = 0.0; 

    public DataPackage(address, lat, lon) { 
     this.Address = address; 
     this.Latitude = lat; 
     this.Longitude = lon; 
    } 
} 

...

class MapOverlay extends AsyncTask<Void,Void,DataPackage> { 

    @Override 
    protected Void doInBackground(Void... arg0) { 
     // ... Conditions and logic TRUNCATED for Clarity! 
     // This would exist inside of your try block 
     return new DataPackage(addressString, latitude, longitude); 
     // ... Rest of code 
    } 

    //... 

    protected void onPostExecute(DataPackage result) { 
     //Logic that updates the UI based on information in DataPackage object. 
    } 
} 
+0

Спасибо за это очень полезный процесс и нити ссылки. Я должен был знать это, ошибка Нооби. В любом случае я сделал то, что вы предложили, но теперь долгота и широта в «etlatitude.setText и etlongitude.setText» дают мне ошибки, потому что «double latitude = location.getLatitude() и double longitude = location.getLongitude();» находятся в doInBackground. Должен ли я создать строку? –

+0

@JohnNguyen Я знаю, что мне поверите! Да, вам придется отделить сбор данных и логику отображения, к счастью, «AsyncTask» обрабатывает всю тяжелую работу для вас. В определении вашей задачи вы можете изменить его, чтобы ожидать нужные вам данные, а затем вернуться из 'doInBackground()', которые будут отображаться для 'onPostExecute()' для вас. Я обновлю свой ответ на примере. –

+0

Извините, мне потребовалось столько времени, чтобы ответить. Я экспериментировал с тем, что вы предложили. Я немного запутался в «классе DataPackage», но не беспокойтесь, я буду продолжать пытаться, пока не получу его. Вы отлично справились со мной в правильном направлении, и за это я благодарю вас Квинтин. В конце концов я это получу! –

2
TextView scrollview = (TextView) findViewById(R.id.scrollview); 
scrollview.setText("Your location:" + "\n" 
         + "(Accurate to 500 meters)" + "\n" + (addressString)); 

напишите вышеуказанный код в onPostExecute() не в doInBackground(). in doInbackground() мы делаем только связанную с сетью задачу, и все связанные с UI задачи должны быть в onPostExecute().