0

我创建了一个活动,它使用谷歌地图生成 UI 并显示用户位置,其开头为:

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

    Button myLocationBtn = (Button)findViewById(R.id.myLocationBtn);
    Button searchRequest = (Button)findViewById(R.id.searchRequest);
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    myLocationBtn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            touched = false;
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
        }
    });
    searchRequest.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            locationManager.removeUpdates(locationListener);
            onSearchRequested();
        }
    });
    initialiseMapView();
  }

这个屏幕需要一段时间才能加载,我认为这是实际调用和运行地图信息并获取用户位置的结果,它在我的方法 initialiseMapView(); 中运行。所以我尝试如下引入AsyncTask:

private class loadMap extends AsyncTask<String, Integer, String>{

    @Override
    protected String doInBackground(String... params) {
        initialiseMapView();
        return null;
    }
}

我在原始代码中所做的只是更改了 initialiseMapView(); 到新的 loadMap().execute();。每次我尝试运行此活动时应用程序都会崩溃,我相信这是因为 initialiseMapView 方法不在 loadMap 类中,但我不确定。

请帮忙 :(


这是initialiseMapView方法:

private void initialiseMapView() {

      mapView = (MapView) findViewById(R.id.mapView);
      mapController = mapView.getController();

      locationListener = new GPSLocationListener();
      locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);

      mapView.setBuiltInZoomControls(true);
      mapView.setSatellite(false);

      GeoPoint startPoint = new GeoPoint((int)(51.500152 * 1E6), (int)(-0.126236 * 1E6));
      mapController.setCenter(startPoint);

      mapController.setZoom(mapView.getZoomLevel());

      mapController.setZoom(14);

      mapFromQuery("london");

      mapView.invalidate();
  }

如果无法做到这一点,是否有某种方法可以在内容加载时显示屏幕?

4

3 回答 3

1

你不能打电话

初始化地图视图();

在 doInBackground() 方法中,因为它运行在与 UI 线程不同的线程上。

于 2012-06-09T15:25:39.390 回答
0

为了扩展其他人所说的内容,您的 AsyncTask 子类应实现以下内容:

onPreExecute() 在后台任务开始之前在 UI 线程上执行。这可能是初始化地图视图的理想位置。

doInBackground() 在后台执行,不得尝试执行任何 UI 功能。这是拨打网络电话和下载地图数据的理想场所。

如果您想从后台任务更新您的 UI,请调用 publishProgress(),这将导致在 UI 线程中调用 onProgressUpdate()。

示例代码:

  class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
      protected Long doInBackground(URL... urls) {
      int count = urls.length;
      long totalSize = 0;
      for( int i = 0; i < count; ++i) {
          totalSize += Downloader.downloadFile(urls[i]);
          publishProgress((int)((i/(float)count)*100));
      }
      return totalSize;
      }

      protected void onProgressUpdate(Integer... progress) {
      setProgressPercent(progress[0]);
      }

      protected void onPostExecute(Long result) {
      showDialog("Downloaded " + result + " bytes");
      }
  }

  ...

  new DownloadFilesTask().execute(url1, url2, url3);

ETA:还有几件事要考虑。每当您有一个线程在后台运行时,您都必须考虑前台任务随时可能消失的可能性。例如,如果用户在数据仍在加载时退出应用程序,或者用户甚至旋转设备。

如果您的 onProgressUpdate() 方法引用了 myMapView,请考虑 myMapView 可能不再是有效的 MapView 对象。(我假设 Android 框架知道忽略不再相关的 View 对象的更新,否则应用程序将到处失败。)

如果您的后台任务是 CPU 密集型的,您可以考虑调用 cancel()(例如在 onStop() 中)告诉后台任务放弃它的工作。或者更好的是,使用 onRetainNonConfigurationInstance() 将对后台线程的引用传递给应用程序的新实例,以便后台任务可以不间断地继续其工作。

于 2012-06-09T18:46:39.450 回答
0

您不能work related to UI在 initialiseMapView 中执行任何操作,因为它是从 doInBackground 调用的,所以请确认相同............

于 2012-06-09T15:24:01.623 回答