Reputation: 557
Would anyone know why The AsyncTask keeps crashing? Basically in my app, I would like to get the GPS coordinates and have it animate to my position in mapview. Then I would like to use GeoCode to display the current address of my position.
Before I started experimenting with AsyncTask, the app displayed everything perfectly, (Shows current position on map, and tells me which address I am nearest and displays it in a textview) however, it was very slow and laggy because I didnt implement AsyncTask. Now that I have implemented AsyncTask, it gives me errors. Could anyone help?
Heres my code:
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;
}
}
Here are my logs:
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
Thanks, guys.
Upvotes: 0
Views: 198
Reputation: 82335
Your code is crashing your application because you are attempting to access controls on the UI thread without a handler and in the wrong area of execution.
You should read up on AsyncTask
and how to properly handle interaction with the UI. There is very good information on that page.
To update your UI, you should implement
onPostExecute()
, which delivers the result fromdoInBackground()
and runs in the UI thread, so you can safely update your UI.
The relevant breaking code in your that needs to be moved to 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));
Edit: Added example from comment discussion.
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.
}
}
Upvotes: 1
Reputation: 34765
TextView scrollview = (TextView) findViewById(R.id.scrollview);
scrollview.setText("Your location:" + "\n"
+ "(Accurate to 500 meters)" + "\n" + (addressString));
write the above code in onPostExecute() not in doInBackground(). in doInbackground() we do only network related task and all the UI related task must be in onPostExecute().
Upvotes: 2