【问题标题】:How to perform gui operation in doInBackground method?如何在 doInBackground 方法中执行 gui 操作?
【发布时间】:2012-10-11 18:24:16
【问题描述】:

我的应用程序读取用户选择的包含地址的文件,然后在完成地理编码后显示在地图视图上。为了避免挂起应用程序,导入和地理编码在 AsyncTask 中完成。

public class LoadOverlayAsync extends AsyncTask<Uri, Integer, StopsOverlay> {

    Context context;
    MapView mapView;
    Drawable drawable;

    public LoadOverlayAsync(Context con, MapView mv, Drawable dw)
    {
        context = con;
        mapView = mv;
        drawable = dw;
    }

    protected StopsOverlay doInBackground(Uri... uris)
    {
        StringBuilder text = new StringBuilder();
        StopsOverlay stopsOverlay = new StopsOverlay(drawable, context);
        Geocoder geo = new Geocoder(context, Locale.US);

        try
        {   
            File file = new File(new URI(uris[0].toString()));

            BufferedReader br = new BufferedReader(new FileReader(file));
            String line;

            while ((line = br.readLine()) != null)
            {
                StopOverlay stopOverlay = null;
                String[] tempLine = line.split("~");
                List<Address> results = geo.getFromLocationName(tempLine[4] + " " + tempLine[5] + " " + tempLine[7] + " " + tempLine[8], 10);

                if (results.size() > 0)
                {
                    Toast progressToast = Toast.makeText(context, "More than one yo", 1000);
                    progressToast.show();
                }
                else if (results.size() == 1)
                {
                    Address addr = results.get(0);
                    GeoPoint mPoint = new GeoPoint((int)(addr.getLatitude() * 1E6), (int)(addr.getLongitude() * 1E6));
                    stopOverlay = new StopOverlay(mPoint, tempLine);
                }

                if (stopOverlay != null)
                {
                    stopsOverlay.addOverlay(stopOverlay);
                }
                //List<Address> results = geo.getFromLocationName(locationName, maxResults)

            }

        } catch (URISyntaxException e) {
            showErrorToast(e.toString());
            //e.printStackTrace();
        } catch (FileNotFoundException e) {
            showErrorToast(e.toString());
            //e.printStackTrace();
        } catch (IOException e) {
            showErrorToast(e.toString());
            //e.printStackTrace();
        }
        return stopsOverlay;
    }

    protected void onProgressUpdate(Integer... progress)
    {
        Toast progressToast = Toast.makeText(context, "Loaded " + progress.toString(), 1000);
        progressToast.show();
    }

    protected void onPostExecute(StopsOverlay so)
    {
        //mapView.getOverlays().add(so);
        Toast progressToast = Toast.makeText(context, "Done geocoding", 1000);
        progressToast.show();
    }

    protected void showErrorToast(String msg)
    {
        Toast Newtoast = Toast.makeText(context, msg, 10000);
        Newtoast.show();
    }
}

但如果地理编码失败,我希望弹出一个对话框让用户编辑地址。这需要在 doInBackground 中调用 gui 方法。什么是一个好的解决方法?

【问题讨论】:

    标签: android user-interface android-asynctask


    【解决方案1】:

    您必须在 onPostExecute 方法中处理它。也许将它设计为 onPostExecute 的 null 参数表明它失败了,所以在这种情况下会弹出对话框。

    【讨论】:

      【解决方案2】:

      如果您不想更改 StopsOverlay 的 Result 类型,那么您可以在 doInBackground 中设置一些成员字段,然后在 onPostExecute 中检查这些成员字段并在此时显示您的错误 UI。

      请注意,这是安全的,建议按照AsyncTask docs:

      AsyncTask 保证所有回调调用都以这样一种方式同步,即以下操作在没有显式同步的情况下是安全的。

      在doInBackground(Params...)中设置成员字段,在onProgressUpdate(Progress...)和onPostExecute(Result)中引用。

      例如,您可以声明一个字段:

      private boolean mTooManyResults = false;
      

      然后将其更改为在doInBackground 中,您的代码如下:

      if (results.size() > 0)
      {
          mTooManyResults = true;
      }
      

      然后在onPostExecute:

      if (mTooManyResults)
      {
          // notify user about error
          Toast progressToast = Toast.makeText(context, "More than one yo", 1000);
          progressToast.show();
      } else
      {
          // notify user about success
          Toast progressToast = Toast.makeText(context, "Done geocoding", 1000);
          progressToast.show();
      }
      

      【讨论】:

      • 还有一件事,我需要传递行数据(无法解码的那个) String[] tempLine = line.split("~");调用对话框的方法。我正在考虑制作一个地理编码失败的数组。然后在 onPostExecute 中列出它们,让用户对其进行编辑。
      • 您也可以将其设置为成员字段,例如 doInBackground 中的 mGeocodingOutputLines,然后在 PostExecute 上显示。我觉得这样就好了。
      猜你喜欢
      • 2020-08-28
      • 2015-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-17
      • 1970-01-01
      • 2018-11-08
      相关资源
      最近更新 更多