【发布时间】:2025-12-18 06:20:04
【问题描述】:
我有一个自定义 AsyncTask 类,它检查设备是否已授予位置权限,然后它获取最后一个已知位置。如果没有权限,则先向用户请求权限。所以在我的 doInBackground 函数中,我需要调用 mGoogleApiClient.connect() 这将触发 onConnected 函数。可以看出,doInBackground需要等待onConnected,否则返回null对象lastKnownLocation。我的问题是如何让 doInBackground 等待 onConnected?
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);}
【问题讨论】:
-
我不能使用 while(lastKnownLocation == null) {} 来等待对象,因为在某些情况下该对象可能为空。
-
检查CompletableFuture 并使用
get来“在必要时等待此未来完成,然后返回其结果。” -
我终于找到了解决办法。但也感谢 Lior 指出工作流程问题。我创建了一个变量 private boolean onConnectedCompleted = false;在 onConnected() 中,我添加 onConnectedCompleted = true;在最后一次。然后在我的 doInBackground 中我只需要检查这个条件。
标签: java android multithreading android-asynctask