Пауза, пока переменная не изменилась - PullRequest
0 голосов
/ 17 марта 2012

У меня вопрос: как приостановить действие, пока не изменится определенная переменная?

Я написал 2 класса, один для LocationListener и один, который создает экземпляр этого класса LocationListener:

Первый класс:

LocationGetter locgetter = new LocationGetter();
LocationManager locmanag = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locmanag.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locgetter);
mLat = locgetter.getLat();
mLong = locgetter.getLon();

Класс LocationListener:

public class LocationGetter implements LocationListener {

double mLat = 0.0;
double mLong = 0.0;

@Override
public void onLocationChanged(Location location) {
if(location != null){
    mLat = location.getLatitude();
    mLong = location.getLongitude();
}

Теперь я хочу, чтобы код в первом классе приостанавливался до тех пор, пока получатели getLatitude и getLongitude фактически не возвращают значение, отличное от 0. Есть причина, по которой я не хочу продолжать до получения долготы и широты, я покажу индикатор выполнения, если это работает. Я знаю, что метод onLocationChanged будет запускаться только при наличии местоположения, но первый класс все равно продолжит выполняться.

Я действительно новичок в Android, поэтому извините, если я упустил что-то совершенно очевидное.

Ответы [ 3 ]

2 голосов
/ 17 марта 2012

Ну, вы могли бы сделать

while (value == 0.0) {
    // do nothing
}
// now use value

но это действительно плохая идея. Вы получите «Приложение не отвечает». Также Вы не должны приостанавливать свою активность, никогда - и это не обязательно.

Что вам нужно сделать, это добавить способ уведомления вашего кода, который хочет использовать значения после их изменения. Самый простой способ использования LocationListeners - реализовать их непосредственно в своей деятельности. вот так:

class MyActivity extends Activity implements LocationListener {
    onCreate() {
        locmanag.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
    }

    public void onLocationChanged(Location location) {
        // now change the ui. This is called on UI thread.
    }
}

Если вы хотите, чтобы местоположение обрабатывалось другим классом, вы все равно можете уведомить свою активность об изменениях.

Если вы хотите использовать LocationListener только из одного действия, которое будет работать:

class MyActivity extends Activity {
    private LocationGetter mGetter;

    onCreate() {
        mGetter = new LocationGetter(this);
        locmanag.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mGetter);
    }

    public void somethingHappend() {
        mGetter.getLat();
    }
}

public class LocationGetter implements LocationListener {

    private final MyActivity mActivity;
    public LocationGetter(MyActivity activity) {
        mActivity= activity;
    }

    @Override
    public void onLocationChanged(Location location) {
    if(location != null){
        mLat = location.getLatitude();
        mLong = location.getLongitude();
        if (mActivity!= null) {
            mActivity.somethingHappend();
        }
    }

    public long getLat() {
        return mLat;
    }
}

Если вы хотите использовать LocationListener из разных видов деятельности, вы должны реализовать общий интерфейс (как у LocationListener)

class MyActivity extends Activity implements LocationGetter.MyCallback {
    private LocationGetter mGetter;

    onCreate() {
        mGetter = new LocationGetter(this);
        locmanag.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mGetter);
    }

    public void somethingHappend() {
        mGetter.getLat();
    }
}

public class LocationGetter implements LocationListener {
    public Interface MyCallback {
        // you could pass lat + long here
        public void somethingHappend();
    }

    private final MyCallback mCallback;
    public LocationGetter(MyCallback callback) {
        mCallback = callback;
    }

    @Override
    public void onLocationChanged(Location location) {
    if(location != null){
        mLat = location.getLatitude();
        mLong = location.getLongitude();
        if (mCallback != null) {
            mCallback.somethingHappend();
        }
    }

    public long getLat() {
        return mLat;
    }
}

Вместо создания нового интерфейса обратного вызова вы также можете использовать LocationListener из всех ваших действий. Работает также, но не показывает, как работают эти обратные вызовы:)

Другая возможность заключается в использовании, например, Обработчик (особенно если другая вещь выполняется в другом потоке)

class MyActivity extends Activity implements Handler.Callback {
    private Handler mHandler;

    onCreate() {
        mHandler = new Handler(this);
        mGetter = new LocationGetter(mHandler);
        locmanag.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mGetter);
    }

    public boolean handleMessage(Message msg) {
        // msg.what would be 0, that's what we send
        mGetter.getLat();
        // we are in UI thread here. safe to modify.
        return true;
    }
}

public class LocationGetter implements LocationListener {

    private final Handler mHandler;
    public LocationGetter(Handler handler) {
        mHandler = handler;
    }

    @Override
    public void onLocationChanged(Location location) {
    if(location != null){
        mLat = location.getLatitude();
        mLong = location.getLongitude();
        if (mHandler != null) {
            // you can send a lot more here
            mHandler.sendEmptyMessage(0);
        }
    }

    public long getLat() {
        return mLat;
    }
}

Кроме того, ожидание LocationListener даже невозможно, если вы попробуете это из своего потока пользовательского интерфейса, так как вы получите обновление в потоке пользовательского интерфейса, которое заблокировано вашим ожиданием. Таким образом, вы никогда не получите обновление.

1 голос
/ 17 марта 2012

Подождите, это хороший вариант, если вы многопоточны, так как он прекрасно работает с notify () и notifyAll ();

http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#wait()

0 голосов
/ 17 марта 2012

Я бы предложил использовать некоторую форму синхронизации, например java.util.concurrent.CyclicBarrier. Звоните CyclicBarrier#await() в Thread-1, и тогда он будет ждать, пока вы также не вызовете его в Thread-2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...