0

有谁知道为什么 AsyncTask 不断崩溃?基本上在我的应用程序中,我想获取 GPS 坐标并让它动画到我在 mapview 中的位置。然后我想使用 GeoCode 来显示我所在位置的当前地址。

在我开始尝试使用 AsyncTask 之前,该应用程序完美地显示了所有内容(在地图上显示当前位置,并告诉我最近的地址并在文本视图中显示它)但是,它非常缓慢且滞后,因为我没有实现 AsyncTask。现在我已经实现了 AsyncTask,它给了我错误。有人可以帮忙吗?

这是我的代码:

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

多谢你们。

4

2 回答 2

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

将上面的代码写在 onPostExecute() 中而不是 doInBackground() 中。在 doInbackground() 中,我们只执行与网络相关的任务,并且所有与 UI 相关的任务都必须在 onPostExecute() 中。

于 2012-04-12T16:29:46.510 回答
1

您的代码正在使您的应用程序崩溃,因为您试图在没有处理程序的情况下访问 UI 线程上的控件并且在错误的执行区域中。

您应该阅读AsyncTask并了解如何正确处理与 UI 的交互。该页面上有非常好的信息。

要更新您的 UI,您应该实现onPostExecute(),它从 UI 线程传递结果doInBackground()并在 UI 线程中运行,这样您就可以安全地更新您的 UI。

您需要将相关的中断代码移至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.
    }
}
于 2012-04-12T16:29:55.980 回答