Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使doInBackground()等待AyncTask类中的另一个函数?_Java_Android_Multithreading_Android Asynctask - Fatal编程技术网

Java 如何使doInBackground()等待AyncTask类中的另一个函数?

Java 如何使doInBackground()等待AyncTask类中的另一个函数?,java,android,multithreading,android-asynctask,Java,Android,Multithreading,Android Asynctask,我有一个自定义的AsyncTask类,它检查设备是否已授予位置权限,然后获取最后一个已知位置。如果它没有权限,它会首先向用户请求权限。所以在我的doInBackground函数中,我需要调用mgoogleapclient.connect(),这将触发onConnected函数。可以看出,doInBackground需要等待onConnected,否则它将返回null对象lastKnownLocation。我的问题是如何让后台等待连接 public class GetLocationTask ex

我有一个自定义的AsyncTask类,它检查设备是否已授予位置权限,然后获取最后一个已知位置。如果它没有权限,它会首先向用户请求权限。所以在我的doInBackground函数中,我需要调用mgoogleapclient.connect(),这将触发onConnected函数。可以看出,doInBackground需要等待onConnected,否则它将返回null对象lastKnownLocation。我的问题是如何让后台等待连接

public class GetLocationTask extends AsyncTask<Void, Void, Location> implements GoogleApiClient.ConnectionCallbacks
    , GoogleApiClient.OnConnectionFailedListener {

private Context context;
private Activity activity;
private GoogleApiClient mGoogleApiClient;
private Location lastKnownLocation = null; //In case the users reject location permission request, we might initialize the location to something interesting
public AsyncResponseForLocation delegate = null;
private static final int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;

public GetLocationTask(Activity activity, Context context) {
    this.activity = activity;
    this.context = context;
}

@Override
protected Location doInBackground(Void... params) {
    if (mGoogleApiClient == null) {
        mGoogleApiClient = new GoogleApiClient.Builder(context)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }
    mGoogleApiClient.connect();
    return lastKnownLocation;
}

@Override
public void onConnected(@Nullable Bundle bundle) {

    if (ActivityCompat.checkSelfPermission(context,
            android.Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(context,
            android.Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

        ActivityCompat.requestPermissions(activity,
                new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
                MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
    }
    lastKnownLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}

@Override
public void onConnectionSuspended(int i) {

}


@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

@Override
protected void onPostExecute(Location location) {
    delegate.processFinish(location);
}


public interface AsyncResponseForLocation {

void processFinish(Location location);}
公共类GetLocationTask扩展AsyncTask实现GoogleAppClient.ConnectionCallbacks
,GoogleApiClient.OnConnectionFailedListener{
私人语境;
私人活动;
私人GoogleapClient MGoogleapClient;
私有位置lastKnownLocation=null;//如果用户拒绝位置权限请求,我们可能会将该位置初始化为感兴趣的内容
公共AsyncResponseForLocation委托=null;
私有静态final int MY\u PERMISSIONS\u REQUEST\u ACCESS\u FINE\u LOCATION=1;
公共GetLocationTask(活动、上下文){
这个。活动=活动;
this.context=上下文;
}
@凌驾
受保护位置doInBackground(无效…参数){
if(mGoogleApiClient==null){
mgoogleapclient=新的Googleapclient.Builder(上下文)
.addConnectionCallbacks(此)
.addOnConnectionFailedListener(此)
.addApi(LocationServices.API)
.build();
}
mGoogleApiClient.connect();
返回最后一个位置;
}
@凌驾
未连接的公共无效(@Nullable Bundle){
if(ActivityCompat.checkSelfPermission)(上下文,
android.Manifest.permission.ACCESS\u FINE\u位置)
!=已授予PackageManager.PERMISSION\u权限
&&ActivityCompat.checkSelfPermission(上下文,
android.Manifest.permission.ACCESS\u\u位置)
!=PackageManager.权限(已授予){
ActivityCompat.requestPermissions(活动,
新字符串[]{android.Manifest.permission.ACCESS\u FINE\u LOCATION},
我的权限、请求、访问、位置);
}
lastKnownLocation=LocationServices.FusedLocationApi.getLastLocation(mgoogleapClient);
}
@凌驾
公共空间连接暂停(int i){
}
@凌驾
public void onconnection失败(@NonNull ConnectionResult ConnectionResult){
}
@凌驾
受保护的void onPostExecute(位置){
委托.进程完成(位置);
}
公共接口AsyncResponseForLocation{
void processFinish(位置);}

执行一个Timertask,每5秒运行一次,以检查条件是否已连接()

试试下面的代码

   private void startTimer(){
            mTimer1 = new Timer();
            mTt1 = new TimerTask() {
                public void run() {
                    mTimerHandler.post(new Runnable() {
                        public void run(){
                            if(isConnected){

                            //call the Async task
                               }
                        }
                    });
                }
            };

        mTimer1.schedule(mTt1, 1, 5000);
    }

将此添加到
doInBackground()
方法之前。
AsyncTask()
将首先执行
onPreExecute()
,然后执行
doInBackground()


您的流量不正确,在您尝试获取位置检查之前,如果您有权限

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
            Manifest.permission.ACCESS_FINE_LOCATION)
    != PackageManager.PERMISSION_GRANTED) {

// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
        Manifest.permission.ACCESS_FINE_LOCATION)) {

    // Show an expanation to the user *asynchronously* -- don't block
    // this thread waiting for the user's response! After the user
    // sees the explanation, try again to request the permission.

} else {

    // No explanation needed, we can request the permission.

    ActivityCompat.requestPermissions(thisActivity,
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
            MY_PERMISSIONS_REQUEST_LOCATION);

    // MY_PERMISSIONS_REQUEST_LOCATION is an
    // app-defined int constant. The callback method gets the
    // result of the request.
} else{
 // Run your async task here(you have got location permission already)
 new GetLocationTask(Activity).execute();
}
当用户需要批准您的权限请求时,您必须处理onRequestPermissionsResult方法:

@Override
public void onRequestPermissionsResult(int requestCode,
    String permissions[], int[] grantResults) {
switch (requestCode) {
    case MY_PERMISSIONS_REQUEST_LOCATION: {
        // If request is cancelled, the result arrays are empty.
        if (grantResults.length > 0
            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            // permission was granted, Execute the asynctask here
            new GetLocationTask(Activity).execute();
        } else {

            // permission denied, boo! Disable the
            // functionality that depends on this permission.
        }
        return;
    }

    // other 'case' lines to check for other
    // permissions this app might request
}
}

我无法使用while(lastnownlocation==null){}等待对象,因为在某些情况下该对象可能为null。请选中并使用
get
以“在必要时等待此未来完成,然后返回其结果。”我终于找到了解决这个问题的方法。但也要感谢Lior指出了工作流程问题。我创建了一个变量private boolean onConnectedCompleted=false;在onConnected()中,我上一次添加了onConnectedCompleted=true;。然后在我的doInBackground中,我只需要检查这个条件。
@Override
public void onRequestPermissionsResult(int requestCode,
    String permissions[], int[] grantResults) {
switch (requestCode) {
    case MY_PERMISSIONS_REQUEST_LOCATION: {
        // If request is cancelled, the result arrays are empty.
        if (grantResults.length > 0
            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            // permission was granted, Execute the asynctask here
            new GetLocationTask(Activity).execute();
        } else {

            // permission denied, boo! Disable the
            // functionality that depends on this permission.
        }
        return;
    }

    // other 'case' lines to check for other
    // permissions this app might request
}
}