Edited: I need to change the values of several variables as they run several times thorugh a timer. I need to keep updating the values with every iteration through the timer
The main concern is whether a variable inside the anonymous class instance can be resolved at run-time. It is not a must to make a variable final as long as it is guaranteed that the variable is inside the run-time scope. For example, please see the two variables _statusMessage and _statusTextView inside updateStatus() method.
public class WorkerService extends Service {
Worker _worker;
ExecutorService _executorService;
ScheduledExecutorService _scheduledStopService;
TextView _statusTextView;
@Override
public void onCreate() {
_worker = new Worker(this);
_worker.monitorGpsInBackground();
// To get a thread pool service containing merely one thread
_executorService = Executors.newSingleThreadExecutor();
// schedule something to run in the future
_scheduledStopService = Executors.newSingleThreadScheduledExecutor();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
ServiceRunnable runnable = new ServiceRunnable(this, startId);
_executorService.execute(runnable);
// the return value tells what the OS should
// do if this service is killed for resource reasons
// 1. START_STICKY: the OS restarts the service when resources become
// available by passing a null intent to onStartCommand
// 2. START_REDELIVER_INTENT: the OS restarts the service when resources
// become available by passing the last intent that was passed to the
// service before it was killed to onStartCommand
// 3. START_NOT_STICKY: just wait for next call to startService, no
// auto-restart
return Service.START_NOT_STICKY;
}
@Override
public void onDestroy() {
_worker.stopGpsMonitoring();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
class ServiceRunnable implements Runnable {
WorkerService _theService;
int _startId;
String _statusMessage;
public ServiceRunnable(WorkerService theService, int startId) {
_theService = theService;
_startId = startId;
}
@Override
public void run() {
_statusTextView = MyActivity.getActivityStatusView();
// get most recently available location as a latitude /
// longtitude
Location location = _worker.getLocation();
updateStatus("Starting");
// convert lat/lng to a human-readable address
String address = _worker.reverseGeocode(location);
updateStatus("Reverse geocoding");
// Write the location and address out to a file
_worker.save(location, address, "ResponsiveUx.out");
updateStatus("Done");
DelayedStopRequest stopRequest = new DelayedStopRequest(_theService, _startId);
// schedule a stopRequest after 10 seconds
_theService._scheduledStopService.schedule(stopRequest, 10, TimeUnit.SECONDS);
}
void updateStatus(String message) {
_statusMessage = message;
if (_statusTextView != null) {
_statusTextView.post(new Runnable() {
@Override
public void run() {
_statusTextView.setText(_statusMessage);
}
});
}
}
}