在周期性任务中等待异步回调?
Wait for an async callback in a periodic task?
我想每 4 小时左右检查一次用户的位置,我不想离开我的应用程序 运行 执行此操作。看起来将 GcmTaskService 与 PeriodicTask 一起使用会让我的服务被调用(当应用程序在 Android 6+ 停止时,WakefulBroadcastReceiver 对启动任务有限制),并且它将兼容回 Android 4.4 (与 JobScheduler 不同)- 我支持的最低 Android 版本。
问题是 GcmTaskService 的 onRunTask 方法是同步的,但我想用它来请求位置并处理结果(LocationManager 将异步调用我的 LocationListener 实现)。
应该如何处理?
使用简单的wait/notify:
private interface RunnableLocationListener extends Runnable, LocationListener {}
@Override
public int onRunTask (TaskParams params) {
final Object monitor = new Object();
final AtomicBoolean located = new AtomicBoolean();
new Thread(new RunnableLocationListener() {
Context context = PeriodicCollector.this;
public void run() {
Criteria criteria = new Criteria();
criteria.setHorizontalAccuracy(Criteria.ACCURACY_HIGH);
LocationManager locationManager = locationManager = (LocationManager)PeriodicCollector.this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestSingleUpdate(criteria, this, Looper.getMainLooper());
}
@Override
public void onLocationChanged(Location location) {
// handle location here
synchronized (monitor) {
located.set(true);
monitor.notifyAll();
}
}
@Override public void onProviderDisabled(String s) {}
@Override public void onProviderEnabled(String s) {}
@Override public void onStatusChanged(String s, int i, Bundle b) {}
}).start();
int status = GcmNetworkManager.RESULT_FAILURE;
try {
synchronized (monitor) {
if (!located.get()) {
monitor.wait();
}
}
} catch (InterruptedException e) {
status = GcmNetworkManager.RESULT_SUCCESS;
}
return status;
}
我想每 4 小时左右检查一次用户的位置,我不想离开我的应用程序 运行 执行此操作。看起来将 GcmTaskService 与 PeriodicTask 一起使用会让我的服务被调用(当应用程序在 Android 6+ 停止时,WakefulBroadcastReceiver 对启动任务有限制),并且它将兼容回 Android 4.4 (与 JobScheduler 不同)- 我支持的最低 Android 版本。
问题是 GcmTaskService 的 onRunTask 方法是同步的,但我想用它来请求位置并处理结果(LocationManager 将异步调用我的 LocationListener 实现)。
应该如何处理?
使用简单的wait/notify:
private interface RunnableLocationListener extends Runnable, LocationListener {}
@Override
public int onRunTask (TaskParams params) {
final Object monitor = new Object();
final AtomicBoolean located = new AtomicBoolean();
new Thread(new RunnableLocationListener() {
Context context = PeriodicCollector.this;
public void run() {
Criteria criteria = new Criteria();
criteria.setHorizontalAccuracy(Criteria.ACCURACY_HIGH);
LocationManager locationManager = locationManager = (LocationManager)PeriodicCollector.this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestSingleUpdate(criteria, this, Looper.getMainLooper());
}
@Override
public void onLocationChanged(Location location) {
// handle location here
synchronized (monitor) {
located.set(true);
monitor.notifyAll();
}
}
@Override public void onProviderDisabled(String s) {}
@Override public void onProviderEnabled(String s) {}
@Override public void onStatusChanged(String s, int i, Bundle b) {}
}).start();
int status = GcmNetworkManager.RESULT_FAILURE;
try {
synchronized (monitor) {
if (!located.get()) {
monitor.wait();
}
}
} catch (InterruptedException e) {
status = GcmNetworkManager.RESULT_SUCCESS;
}
return status;
}