Java 如何等待requestLocationUpdates()回调意图完成?

Java 如何等待requestLocationUpdates()回调意图完成?,java,android,asynchronous,android-fusedlocation,Java,Android,Asynchronous,Android Fusedlocation,我想等待中的回调结束。带超时的while循环是最佳解决方案吗?下面是一个示例,sans timeout 通常我会等待异步服务完成,但我不知道如何将其与requestLocationUpdates()一起使用 如果您对RxJava/RxAndroid有点熟悉,那么您可以将方法调用封装在一个可观察的(或可调用的、单一的、任何您认为最好的)中,在UI之外的另一个线程上运行它,然后一旦您从方法中获得结果,您就可以在主线程上接收它,并对它执行任何您想要的操作 在代码中,它将如下所示: Observable

我想等待中的回调结束。带超时的while循环是最佳解决方案吗?下面是一个示例,sans timeout

通常我会等待异步服务完成,但我不知道如何将其与requestLocationUpdates()一起使用


如果您对RxJava/RxAndroid有点熟悉,那么您可以将方法调用封装在一个可观察的(或可调用的、单一的、任何您认为最好的)中,在UI之外的另一个线程上运行它,然后一旦您从方法中获得结果,您就可以在主线程上接收它,并对它执行任何您想要的操作

在代码中,它将如下所示:

Observable.fromCallable(() -> flpc.requestLocationUpdates(locationRequest, pe))
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(task -> onLocationUpdatesSuccess(task), throwable -> Log.e(TAG, throwable.getMessage()));
    new AsyncTask<Void, Void, Task>() {
            @Override
            protected Task doInBackground(Void... params) {
                return flpc.requestLocationUpdates(locationRequest, pe);
            }

            @Override
            protected void onPostExecute(Task task) {
                onLocationUpdatesSuccess(task)
            }
    }.execute();
否则,另一种解决方案是将您的方法包装在AsyncTask中,例如,您将得到如下结果:

Observable.fromCallable(() -> flpc.requestLocationUpdates(locationRequest, pe))
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(task -> onLocationUpdatesSuccess(task), throwable -> Log.e(TAG, throwable.getMessage()));
    new AsyncTask<Void, Void, Task>() {
            @Override
            protected Task doInBackground(Void... params) {
                return flpc.requestLocationUpdates(locationRequest, pe);
            }

            @Override
            protected void onPostExecute(Task task) {
                onLocationUpdatesSuccess(task)
            }
    }.execute();
newasynctask(){
@凌驾
受保护的任务doInBackground(无效…参数){
返回flpc.RequestLocationUpdate(locationRequest,pe);
}
@凌驾
受保护的void onPostExecute(任务){
onLocationUpdateSuccess(任务)
}
}.execute();

以下是我最后做的事情:

使用手动唤醒锁。在类中声明静态wakelock变量。还定义了两个方法:acquire()和release()

acquire()实例化wakelock并在类中为其分配静态wakelock变量。它是一个实例方法(不是静态的),因为它使用需要上下文的PowerManager

release()是一个静态方法,因此其他类可以调用它。它会释放唤醒锁。我使用了一个带有wakelock计数器的单态wakelock,在调用它时减小计数器,在计数器为零时释放wakelock。但是柜台是完全可选的

所有这些的“诀窍”是创建一个实例wakelock并将其分配给一个静态变量。这允许在无法访问我的类实例的服务中修改wakelock


与其从类外部调用finish(),不如使用Task.OnCompleteListener()调用finish()。requestLocationUpdates()返回一个任务对象。

以下是我仅获取一个位置的解决方案:

private fun getNewLocation(): Single<Location> =
    Single.create { emitter ->
        locationClient.requestLocationUpdates(locationRequest, object : LocationCallback() {
            override fun onLocationResult(result: LocationResult) {
                locationClient.removeLocationUpdates(this)

                val location = result.locations.firstOrNull()
                if (location != null) {
                    emitter.onSuccess(location)
                } else {
                    emitter.onError(NullPointerException("Null location"))
                }
            }

            override fun onLocationAvailability(result: LocationAvailability) {
                if (!result.isLocationAvailable) {
                    locationClient.removeLocationUpdates(this)
                    emitter.onError(IllegalStateException("Location not available"))
                }
            }
        }, Looper.getMainLooper())
    }

我需要一个wakelock,但这在我最初的问题中并不清楚。所以我选择了另一个答案。