0

私のアプリケーションは、住所を含むユーザーが選択したファイルを読み取り、ジオコーディングが完了するとマップビューに表示します。アプリのハングを回避するために、インポートとジオコーディングは 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

StopsOverlayの結果タイプを変更したくない場合は、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 に答える
0

onPostExecute メソッドで処理する必要があります。おそらく、onPostExecute への null 引数が失敗したことを示すように設計し、その場合はダイアログをポップアップします。

于 2012-10-21T23:00:32.930 に答える