Java Thread.sleep()是否不允许其他线程运行?

Java Thread.sleep()是否不允许其他线程运行?,java,android,multithreading,Java,Android,Multithreading,我正在制作一个Android应用程序,我制作了一个类来分离和管理与获取用户位置相关的代码。由于FusedLocationProviderClient需要一些时间来给出响应并在onSuccess或onFailure侦听器中执行代码,因此我创建了一个方法(waitForLocation()),它基本上会等待一个侦听器被执行或超过时间限制 waitForLocation()方法是一种阻塞方法,它等待gotress变为true,让线程的其余部分继续(如果超过时间限制,gotress也将变为true) 问

我正在制作一个Android应用程序,我制作了一个类来分离和管理与获取用户位置相关的代码。由于FusedLocationProviderClient需要一些时间来给出响应并在onSuccess或onFailure侦听器中执行代码,因此我创建了一个方法(
waitForLocation()
),它基本上会等待一个侦听器被执行或超过时间限制

waitForLocation()
方法是一种阻塞方法,它等待
gotress
变为
true
,让线程的其余部分继续(如果超过时间限制,
gotress
也将变为
true

问题是,为了在
gotResponse
true
之前停止代码流动,我使用了
Thread.sleep()
方法,但所有后台任务,如
倒计时程序和侦听器似乎也与主线程一起冻结(倒计时
没有滴答声,监听器从不执行)

请帮忙! 提前感谢: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;
    }
}
package com.sserrano.stormy;
导入android.app.Activity;
导入android.location.location;
导入android.os.CountDownTimer;
导入android.support.annotation.NonNull;
导入android.util.Log;
导入com.google.android.gms.location.FusedLocationProviderClient;
导入com.google.android.gms.location.LocationServices;
导入com.google.android.gms.tasks.OnFailureListener;
导入com.google.android.gms.tasks.OnSuccessListener;
公共类UserLocationManager{
public static final String TAG=UserLocationManager.class.getSimpleName();
私有FusedLocationProviderClient locationClient;
私人活动不活跃;
私有双[]coords={37.8267,-122.4233},defaultCoords={37.8267,-122.4233};
private volatile boolean gotress=false;
UserLocationManager(活动安装){
this.instActivity=instActivity;
locationClient=LocationServices.getFusedLocationProviderClient(instActivity);
}
public double[]getLastCoords(){
试一试{
locationClient.getLastLocation()。
addOnSuccessListener(instActivity,新OnSuccessListener(){
@凌驾
成功时的公共无效(位置){
如果(位置!=null){
coords=新双精度[]
{location.getLatitude(),location.getLatitude()};
}
gotResponse=true;
}
}).addOnFailureListener(instActivity,新OnFailureListener(){
@凌驾
public void onFailure(@NonNull异常e){
gotResponse=true;
}
});
}捕获(安全异常e){
返回defaultCoords;
}
waitForLocation();
返回坐标;
}
public double[]getDefaultCoords(){
返回defaultCoords;
}
私有void waitForLocation(){
新的倒计时(50005000){
@凌驾
公共无效onFinish(){
gotResponse=true;
w(标记“等待位置请求结果超时”);
}
@凌驾
公共void onTick(长毫秒未完成){
}
};
试一试{
而(!gotResponse){
sleep(Constants.getSleepIntervalDuration());
}
}捕捉(中断异常e){
Log.w(标记,“在等待位置请求的结果时被中断。”+
“应用程序的行为可能与未接收到位置时的行为类似,”+
“即使是。”);
}
gotResponse=false;
}
}
  • 这将使UI线程处于休眠状态。这是绝对不可能的。我担心您对倒计时和异步操作的使用非常错误。请查看更多示例
  • 此外,您忘了在倒计时时调用.start(),onFinish将永远不会发生
  • 将计时器分配给一个成员变量,那么它将一直有效,直到调用onFinish,并且您可以设置您的响应
  • 这将使UI线程处于休眠状态。这是绝对不可能的。我担心您对倒计时和异步操作的使用非常错误。请查看更多示例
  • 此外,您忘了在倒计时时调用.start(),onFinish将永远不会发生
  • 将计时器分配给一个成员变量,那么它将一直有效,直到调用onFinish,并且您可以设置您的响应

  • 如果不希望UI冻结,请不要休眠UI线程。什么调用getLastCoords()?如果不希望UI冻结,请不要休眠UI线程。什么调用getLastCoords()?我想你的意思是“异步”操作。另外,如果您不持有对
    倒计时计时器的引用,则建议它将获得GC'd是不正确的;它注册了一个内部
    处理程序
    ,在计时器完成之前保持一个引用。@greeble31是的,我的手机键盘欺骗了我。它没有得到垃圾收集?很高兴知道,我会尝试一下。我你的意思是“异步”操作。另外,如果您不持有对
    倒计时计时器的引用,则建议它将获得GC'd是不正确的;它注册了一个内部
    处理程序
    ,在计时器完成之前保持一个引用。@greeble31是的,我的手机键盘欺骗了我。它没有得到垃圾收集?很高兴知道,我会尝试一下。