我正在制作一个 Android 应用程序,我制作了一个类来更轻松地分离和管理与获取用户位置相关的代码。由于 FusedLocationProviderClient 需要一些时间来给出响应并执行 onSuccess 或 onFailure 监听器中的代码,因此我创建了一个方法 ( waitForLocation()
),它基本上等到其中一个监听器被执行或超过时间限制。
waitForLocation()
method 是一个阻塞方法,它一直等到 gotResponse
变成 true
让线程的其余部分继续(如果超过时间限制,gotResponse
也将变为 true
)。
问题在于,要阻止代码流动直到 gotResponse
是true
,我正在使用 Thread.sleep()
方法,但所有后台任务,例如 CountDownTimer
并且听众似乎也与主线程一起卡住(CountDownTimer
没有滴答作响,听众永远不会执行)。
求助! 提前致谢:D
这是我的课:
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;
}
}
最佳答案
- 这将使 UI 线程 hibernate 。这是绝对不行的。我担心您对 CountDownTimer 和异步操作的用法理解有误。请查看更多示例。
- 此外,您忘记在 CountDownTimer 上调用 .start() onFinish 永远不会发生。
- 将计时器分配给一个成员变量,然后它将一直存在直到调用 onFinish 并且您可以设置您的 gotResponse。
关于java - Thread.sleep() 是否不让其他线程运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54836529/