0

我的应用程序读取用户选择的包含地址的文件,然后在完成地理编码后显示在 mapview 上。为了避免挂起应用程序,导入和地理编码在 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 方法。什么是一个好的解决方法?

4

2 回答 2

0

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

于 2012-10-21T23:00:32.930 回答
0

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

请注意,这是安全的,并且根据AsyncTask 文档推荐:

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();
}
于 2012-10-21T23:11:45.133 回答