暂停直到变量发生变化

时间:2012-03-17 15:16:18

标签: android date calendar

我有一个问题:在更改某个变量之前,如何暂停活动?

我写了两个类,一个用于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 getter实际返回0以外的值。有一个原因我不想在获得经度和纬度之前继续,我将展示一个进度条,如果这工作。我知道onLocationChanged方法只会在有位置时运行,但第一个类仍会继续执行。

我对Android很新,所以如果我忽略了一些非常明显的东西,请原谅。

3 个答案:

答案 0 :(得分:2)

你可以做到

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

但这是一个非常糟糕的主意。你会得到"应用程序无响应"。也 你不能暂停你的活动,从来没有 - 而且没有必要。

您应该做的是添加一种方法来通知您想要在值发生变化时使用这些值的代码。 LocationListeners最简单的方法是直接在Activity中实现它们。像这样:

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.
    }
}

如果您希望该位置由其他班级处理,您仍然可以通知您的活动有关更改。

如果您只想从一个可以使用的Activity中使用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之外,如果你在Activity UI线程中尝试这样做,那么你甚至不可能,因为你得到了你的等待阻止的UI线程的更新。所以你永远不会得到更新。

答案 1 :(得分:1)

等待是一个不错的选择,如果你是多线程的,因为它适用于notify()和notifyAll();

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

答案 2 :(得分:0)

我建议使用某种形式的同步,例如java.util.concurrent.CyclicBarrier。在Thread-1中调用CyclicBarrier#await()然后它将一直等到你在Thread-2中调用它