0

有人可以帮我弄清楚为什么 AsyncTask 偶尔会崩溃吗?

这是我的代码:

 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 = "No address found";
StringBuilder sb;

private MapController mapController;
private MyLocationOverlay myLocation;

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.enableMyLocation();

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

@Override
protected boolean isRouteDisplayed() {

    // Executes GeoCoding AsyncTask //
    new GeoCoder().execute();

    // 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);
    if (location != null) {

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

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

        // Latitude and Longitude TextView Display Coordinates //
        etlongitude.setText((longitude) + "");
        etlatitude.setText((latitude) + "");

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

    }

    return false;
}

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

    @Override
    protected Void doInBackground(Void... params) {
        Log.d("Class == GeoCoder", "AsyncTask == doInBackGround");

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

        gc = new Geocoder(statuspage.this, 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 = e.toString();
        }
        return null;

    }


    @Override
    protected void onPostExecute(Void result) {

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

        Log.d("Class == GeoCoder", "AsyncTask == onPostExecute");
        return;
    }

}

@Override
protected void onResume() {
    super.onResume();
    myLocation.enableMyLocation();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    new GeoCoder();

}

@Override
protected void onPause() {
    super.onPause();
    new GeoCoder().cancel(true);
    myLocation.disableMyLocation();
}

@Override
public void onStop() {
    super.onStop();
    new GeoCoder().cancel(true);

}

@Override
public void onBackPressed() {
    new GeoCoder().cancel(true);

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

}
 }

这是我的日志:

 04-20 09:23:15.449: D/Class == GeoCoder(22493): AsyncTask == onPostExecute
 04-20 09:23:16.082: D/Dialog(22493): dialog button was clicked
 04-20 09:23:16.136: W/MapActivity(22493): Recycling dispatcher android_maps_conflict_avoidance.com.google.googlenav.datarequest.DataRequestDispatcher@40685938
 04-20 09:23:16.140: V/MapActivity(22493): Recycling map object.
 04-20 09:23:16.167: I/Maps.MyLocationOverlay(22493): Request updates from gps
 04-20 09:23:16.167: I/Maps.MyLocationOverlay(22493): Request updates from network
 04-20 09:23:16.179: I/Maps.MyLocationOverlay(22493): Request updates from gps
 04-20 09:23:16.183: I/Maps.MyLocationOverlay(22493): Request updates from network
 04-20 09:23:16.238: I/MapActivity(22493): Handling network change notification:CONNECTED
 04-20 09:23:16.238: E/MapActivity(22493): Couldn't get connection factory client
 04-20 09:23:16.281: D/Class == GeoCoder(22493): AsyncTask == doInBackGround
 04-20 09:23:16.300: W/dalvikvm(22493): threadid=28: thread exiting with uncaught exception (group=0x40015578)
 04-20 09:23:16.390: E/AndroidRuntime(22493): FATAL EXCEPTION: AsyncTask #16
 04-20 09:23:16.390: E/AndroidRuntime(22493): java.lang.RuntimeException: An error occured while executing doInBackground()
 04-20 09:23:16.390: E/AndroidRuntime(22493):   at android.os.AsyncTask$3.done(AsyncTask.java:200)
 04-20 09:23:16.390: E/AndroidRuntime(22493):   at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
 04-20 09:23:16.390: E/AndroidRuntime(22493):   at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
 04-20 09:23:16.390: E/AndroidRuntime(22493):   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
 04-20 09:23:16.390: E/AndroidRuntime(22493):   at java.util.concurrent.FutureTask.run(FutureTask.java:138)
 04-20 09:23:16.390: E/AndroidRuntime(22493):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
 04-20 09:23:16.390: E/AndroidRuntime(22493):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
 04-20 09:23:16.390: E/AndroidRuntime(22493):   at java.lang.Thread.run(Thread.java:1019)
 04-20 09:23:16.390: E/AndroidRuntime(22493): Caused by: java.lang.NullPointerException
 04-20 09:23:16.390: E/AndroidRuntime(22493):   at com.jetdelivery.mobile.statuspage$GeoCoder.doInBackground(statuspage.java:111)
 04-20 09:23:16.390: E/AndroidRuntime(22493):   at com.jetdelivery.mobile.statuspage$GeoCoder.doInBackground(statuspage.java:1)
 04-20 09:23:16.390: E/AndroidRuntime(22493):   at android.os.AsyncTask$2.call(AsyncTask.java:185)
 04-20 09:23:16.390: E/AndroidRuntime(22493):   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
 04-20 09:23:16.390: E/AndroidRuntime(22493):   ... 4 more

继承人第 111 行:双纬度 = location.getLatitude();

几天来我一直试图弄清楚,尝试在这里搜索,在谷歌上,遵循一些例子,没有运气。

多谢你们!

4

1 回答 1

2

在 isRouteDisplayed() 中初始化位置对象之前启动 GeoCoder 任务。您应该在获取位置并测试 null 后启动它,这意味着在行之后:

if (location != null) {

您还可以在 doInBackground 中测试它的空指针,但没有它,整个方法看起来毫无用处。

崩溃有时会发生,因为您不知道任务何时开始。这意味着有时创建 GeoCoder 任务的线程将继续运行,初始化位置对象而不是任务控制。然而,这只是偶尔发生。在其他情况下,任务在第一个线程到达位置初始化代码之前开始并崩溃。

于 2012-04-20T16:55:54.267 回答