Я делаю приложение для Android и создал класс для более простого разделения и управления кодом, связанным с определением местоположения пользователя. Так как FusedLocationProviderClient требуется некоторое время, чтобы дать ответ и выполнить код внутри слушателей onSuccess или onFailure, я создал метод (waitForLocation()
), который в основном ожидает выполнения одного из слушателей или превышения лимита времени.
Метод waitForLocation()
- это метод блокировки, который ожидает, пока значение gotResponse
станет true
чтобы позволить остальной части потока продолжить (значение gotResponse
также станет true
если превышен лимит времени).
Проблема заключается в том, что для остановки выполнения кода до gotResponse
пор, пока значение gotResponse
станет true
, я использую метод Thread.sleep()
, но все фоновые задачи, такие как CountDownTimer
и слушатели, похоже, также CountDownTimer
вместе с основным поток (CountDownTimer
не тикает и слушатели никогда не выполняются).
Пожалуйста помоги! Заранее спасибо
Это мой класс:
package com.sserrano.stormy;
import android.app.Activity;
import android.location.Location;
import android.os.CountDownTimer;
import android.support.annotation.NonNull;
import android.util.Log;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
public class UserLocationManager {
public static final String TAG = UserLocationManager.class.getSimpleName();
private FusedLocationProviderClient locationClient;
private Activity instActivity;
private double[] coords = {37.8267, -122.4233}, defaultCoords = {37.8267, -122.4233};
private volatile boolean gotResponse = false;
UserLocationManager(Activity instActivity){
this.instActivity = instActivity;
locationClient = LocationServices.getFusedLocationProviderClient(instActivity);
}
public double[] getLastCoords() {
try {
locationClient.getLastLocation().
addOnSuccessListener(instActivity, new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
if(location != null) {
coords = new double[]
{location.getLatitude(), location.getLongitude()};
}
gotResponse = true;
}
}).addOnFailureListener(instActivity, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
gotResponse = true;
}
});
} catch (SecurityException e){
return defaultCoords;
}
waitForLocation();
return coords;
}
public double[] getDefaultCoords(){
return defaultCoords;
}
private void waitForLocation(){
new CountDownTimer(5000, 5000){
@Override
public void onFinish() {
gotResponse = true;
Log.w(TAG, "Timed out waiting the result of the location request.");
}
@Override
public void onTick(long millisUntilFinished) {
}
};
try{
while(!gotResponse) {
Thread.sleep(Constants.getSleepIntervalDuration());
}
} catch (InterruptedException e) {
Log.w(TAG, "Interrupted while waiting the result of the location request." +
" The app will likely act like if the location was not received, " +
"even if it was.");
}
gotResponse = false;
}
}
CountDownTimer
получит GC'd, если вы не держите ссылку на него; он регистрирует внутреннийHandler
который поддерживает ссылку, пока таймер не завершится.