0
我需要將異步FusedLocationApi.getLastLocation調用轉換爲同步。我不是Java的大專家,我不確定我是否做對了。Android FusedLocationApi.getLastLocation同步
我想連接到GoogleApiClient
,然後阻止調用線程,直到收到位置信息或錯誤。逾時超過10秒應視爲錯誤。
它會這樣工作還是onConnected
也會在主線程上調用,它會在那個時候被鎖定?
我也注意到lock.wait(TimeUnit.SECONDS.toMillis(10));
會在正常運行中立即繼續,但在逐步調試中,它會按預期等待10秒鐘。
public class SyncLocationService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
public GoogleApiClient mGoogleApiClient;
public SyncLocationService(Context context) {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
private final Object lock = new Object();
public android.location.Location mLocation;
@Override
public android.location.Location lastLocation() {
mGoogleApiClient.connect();
synchronized (lock) {
try {
lock.wait(TimeUnit.SECONDS.toMillis(10));
} catch (InterruptedException e) {
Log.i("NativeLocationService", "InterruptedException");
}
}
return mLocation;
}
@Override
public void onConnected(@Nullable Bundle bundle) {
try {
mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
mGoogleApiClient.disconnect();
} catch (SecurityException e) {
Log.i("NativeLocationService", "SecurityException");
} finally {
synchronized (lock) {
lock.notify();
}
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
synchronized (lock) {
lock.notify();
}
}
}
基本上我試圖重寫類似的iOS代碼,它使用信號量做它的工作。
var semaphore: DispatchSemaphore!
var location: CLLocation!
func lastLocation() -> location? {
self.semaphore = DispatchSemaphore(value: 0)
self.locationManager.startUpdatingLocation()
_ = self.semaphore!.wait(timeout: .now() + 10) // seconds
self.semaphore = nil
return self.location
}
// MARK: - CLLocationManagerDelegate
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let semaphore = self.semaphore else {
return
}
guard let first = locations.first else {
return
}
self.location = first
self.locationManager.stopUpdatingLocation()
semaphore.signal()
}
看看這個答案:https://stackoverflow.com/questions/36740758/how-to-return-value-on-googleapiclient-onconnected – Entreco