1

シナリオ:

これまでに行ったことは、(テスト目的で) 3 分ごとに更新される GeoCoder を処理する AsyncTask を作成することです。次に、ユーザーの現在のアドレスを含むトースト メッセージを 4 分ごとに表示する TimerTask を設定します。(TimerTasks はコードに含まれていません)

問題は次のとおりです。

アプリを使用しているときはすべて問題ありませんが、アプリがバックグラウンドで実行されている場合、トースト メッセージは、アプリを終了する前にアプリが最後に設定されたアドレスにスタックしたままになります。AsyncTask がバックグラウンドで実行されていることは確かです (LogCats をチェック)。すべてがバックグラウンドで正常に実行されているようです。Toast に現在のアドレスを表示することはできません。

すべての考えや意見をお待ちしております。

これが私のコードです:

 public class statuspage extends MapActivity {

LocationManager locationManager;
MapView mapView;
Criteria criteria;
Location location;
Geocoder gc;
Address address;

String bestProvider;
String LOCATION_SERVICE = "location";
String addressString = "Searching for Nearest Address";
StringBuilder sb;

private MapController mapController;
private MyLocationOverlay myLocation;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.statuspage);

    // Get Mapping Controllers etc //
    mapView = (MapView) findViewById(R.id.mapView);
    mapController = mapView.getController();
    mapController.setZoom(17);
    mapView.setBuiltInZoomControls(true);

    // Add the MyLocationOverlay //
    myLocation = new MyLocationOverlay(this, mapView);
    mapView.getOverlays().add(myLocation);
    myLocation.enableCompass();
    myLocation.enableMyLocation();

    // Animates the map to GPS Position //
    myLocation.runOnFirstFix(new Runnable() {
        @Override
        public void run() {
            mapController.animateTo(myLocation.getMyLocation());

        }
    });
}

@Override
protected boolean isRouteDisplayed() {

    // Location Manager Intiation
    locationManager = (LocationManager) statuspage.this
            .getSystemService(LOCATION_SERVICE);
    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);
    updateWithNewLocation(location);

    locationManager.requestLocationUpdates(bestProvider, 60000, 10,
            locationListener); // 1800000 = 30 Min

    return false;
}

class GeoCoder extends AsyncTask<Void, Void, Void> {

    String lat = "Acquiring";
    String lng = "Acquiring";

    @Override
    protected Void doInBackground(Void... params) {
        if (location != null) {

            /**
             * double latitude = myLocation.getMyLocation().getLatitudeE6();
             * double longitude =
             * myLocation.getMyLocation().getLongitudeE6();
             */

            double latitude = location.getLatitude();
            double longitude = location.getLongitude();

            lat = "" + latitude;
            lng = "" + longitude;

            // gc = new Geocoder(statuspage.this, Locale.getDefault());
            Geocoder gc = new Geocoder(getApplicationContext(),
                    Locale.getDefault());
            try {

                List<Address> addresses = gc.getFromLocation(latitude,
                        longitude, 1);

                sb = new StringBuilder();
                if (addresses != null && addresses.size() > 0) {
                    address = addresses.get(0);

                    int noOfMaxAddressLine = address
                            .getMaxAddressLineIndex();
                    if (noOfMaxAddressLine > 0) {
                        for (int i = 0; i < address
                                .getMaxAddressLineIndex(); i++) {
                            sb.append(address.getAddressLine(i)).append(
                                    "\n");
                        }
                        addressString = sb.toString();

                    }
                }
            } catch (Exception e) {

                addressString = "Sorry, we are trying to find information about this location";
            }

        }
        return null;
    }


    @Override
    protected void onPostExecute(Void result) {
        TextView scrollview = (TextView) findViewById(R.id.scrollview);

        // Latitude and Longitude TextView
        TextView etlongitude = (TextView) findViewById(R.id.etlongitude);
        TextView etlatitude = (TextView) findViewById(R.id.etlatitude);

        // TextView to display GeoCoder Address
        scrollview.setGravity(Gravity.CENTER);
        scrollview.setText("Your location:" + "\n"
                + "(Accurate to 500 meters)" + "\n" + (addressString));

        Log.d("Address", (addressString));

        // Latitude and Longitude TextView Display Coordinates //
        etlongitude.setText(lng);
        etlatitude.setText(lat);

        // Log.d("GeoCoder", "In-Task");

        return;
    }
4

2 に答える 2

0

非同期タスクを使用している場合、バックグラウンドでUIを更新することはできません。バックグラウンドからのスレッド内からUIを接続することはできません。UIを接続する唯一の方法は、onPostExecute()を使用することです。このonPostExecute()関数を使用します。 UIを更新するには、バックグラウンドからメッセージを送信してみてください。実行後は、メッセージを確認してUIを実行してください。これは、確実に役立ちます。

于 2012-05-04T03:48:18.457 に答える
0

私は同じ問題を抱えています。doInBackgroud現在のアクティビティを続行しても問題ありませんが、実行中にアクティビティをonPostExecute終了すると、Toast ラインで終了します。

この問題を解決するには、ハンドラを使用する必要があります:
クラス内

private static final int TOAST  = 0;
private Handler mHandler = null;

OnCreate()

// Creation of the handler to display Toasts
if (mHandler == null) {
    mHandler = new Handler() {
        @Override
        public void handleMessage(Message _msg) {
            switch (_msg.what) {
            case TOAST:
            Toast.makeText(ServerTabHost.this, (String)_msg.obj, Toast.LENGTH_LONG).show();
            break;
            default : break;
        }
        super.handleMessage(_msg);
        }
    };
}

onPostExecute()

Message msg = new Message();
msg.what = TOAST;
msg.obj = "my toast message";
mHandler.sendMessage(msg);

あなたのコードでは、次のようになります。

public class statuspage extends MapActivity {

// These two lines are for the handler
private static final int TOAST  = 0;
private Handler mHandler = null;

LocationManager locationManager;
MapView mapView;
Criteria criteria;
Location location;
Geocoder gc;
Address address;

String bestProvider;
String LOCATION_SERVICE = "location";
String addressString = "Searching for Nearest Address";
StringBuilder sb;

private MapController mapController;
private MyLocationOverlay myLocation;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.statuspage);

    // Get Mapping Controllers etc //
    mapView = (MapView) findViewById(R.id.mapView);
    mapController = mapView.getController();
    mapController.setZoom(17);
    mapView.setBuiltInZoomControls(true);

    // Add the MyLocationOverlay //
    myLocation = new MyLocationOverlay(this, mapView);
    mapView.getOverlays().add(myLocation);
    myLocation.enableCompass();
    myLocation.enableMyLocation();

    // Animates the map to GPS Position //
    myLocation.runOnFirstFix(new Runnable() {
        @Override
        public void run() {
            mapController.animateTo(myLocation.getMyLocation());

        }
    });

    // Creation of the handler to display Toasts
    if (mHandler == null) {
        mHandler = new Handler() {
        @Override
        public void handleMessage(Message _msg) {
            switch (_msg.what) {
                case TOAST:
                Toast.makeText(ServerTabHost.this, (String)_msg.obj, Toast.LENGTH_LONG).show();
                break;
                default : break;
            }
            super.handleMessage(_msg);
            }
        };
    }
}

@Override
protected boolean isRouteDisplayed() {

    // Location Manager Intiation
    locationManager = (LocationManager) statuspage.this
            .getSystemService(LOCATION_SERVICE);
    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);
    updateWithNewLocation(location);

    locationManager.requestLocationUpdates(bestProvider, 60000, 10,
            locationListener); // 1800000 = 30 Min

    return false;
}

class GeoCoder extends AsyncTask<Void, Void, Void> {

    String lat = "Acquiring";
    String lng = "Acquiring";

    @Override
    protected Void doInBackground(Void... params) {
        if (location != null) {

            /**
             * double latitude = myLocation.getMyLocation().getLatitudeE6();
             * double longitude =
             * myLocation.getMyLocation().getLongitudeE6();
             */

            double latitude = location.getLatitude();
            double longitude = location.getLongitude();

            lat = "" + latitude;
            lng = "" + longitude;

            // gc = new Geocoder(statuspage.this, Locale.getDefault());
            Geocoder gc = new Geocoder(getApplicationContext(),
                    Locale.getDefault());
            try {

                List<Address> addresses = gc.getFromLocation(latitude,
                        longitude, 1);

                sb = new StringBuilder();
                if (addresses != null && addresses.size() > 0) {
                    address = addresses.get(0);

                    int noOfMaxAddressLine = address
                            .getMaxAddressLineIndex();
                    if (noOfMaxAddressLine > 0) {
                        for (int i = 0; i < address
                                .getMaxAddressLineIndex(); i++) {
                            sb.append(address.getAddressLine(i)).append(
                                    "\n");
                        }
                        addressString = sb.toString();

                    }
                }
            } catch (Exception e) {

                addressString = "Sorry, we are trying to find information about this location";
            }

        }
        return null;
    }


    @Override
    protected void onPostExecute(Void result) {

        // Sending the Toast message through the handler
        Message msg = new Message();
    msg.what = TOAST;
    msg.obj = "My toast message";
    mHandler.sendMessage(msg);

        TextView scrollview = (TextView) findViewById(R.id.scrollview);

        // Latitude and Longitude TextView
        TextView etlongitude = (TextView) findViewById(R.id.etlongitude);
        TextView etlatitude = (TextView) findViewById(R.id.etlatitude);

        // TextView to display GeoCoder Address
        scrollview.setGravity(Gravity.CENTER);
        scrollview.setText("Your location:" + "\n"
                + "(Accurate to 500 meters)" + "\n" + (addressString));

        Log.d("Address", (addressString));

        // Latitude and Longitude TextView Display Coordinates //
        etlongitude.setText(lng);
        etlatitude.setText(lat);

        // Log.d("GeoCoder", "In-Task");

        return;
    }

個人的には、私は Fragment にいたので、ホスト アクティビティでハンドラーを作成し、それを Fragment コンストラクターに渡す必要がありました。

于 2012-05-04T08:47:29.343 に答える