I need to create an activity that starts a service that monitors the users position and when within a certain zone allow the calling Activity to update its view informing the user.
Since there are a few different ways to work with services I am a little confused to which of these is the correct开发者_如何转开发 one for my situation.
Use the startService()
and stopService()
methods: From what I understand I can't directly talk back to the starting activity. In the google docs there is an example showing how to pass a BroadcastReceiver to the service via a PendingIntent and call it, but I don't think that allow for me to update the running activity's view...or will it?
Bound Service: From the docs it seems that this will allow for 2-way communication between the service and activity, but it was also mentioned that bound services don't run in the background indefinitely. Now I don't need, or even want, the service to run indefinitely, but in the worst case scenario I could need it to run in the bg for at least an hour or two without being killed.
Third (probably not so great) option: Run the location service in a thread in the activity, which will make real-time view updates easy, then in the onPause event, stop the location service in the activity and hand it off to a service via startService()
and use the notification service to alert the user when a defined zone has been entered.
Any advice would be greatly appreciated.
this says
if you want the service to send a result back, then the client that starts the service can create a PendingIntent for a broadcast (with getBroadcast()) and deliver it to the service in the Intent that starts the service. The service can then use the broadcast to deliver a result.
and this says
A bound service typically lives only while it serves another application component and does not run in the background indefinitely.
You can have a Service which is both bound and is started via startService()
. Using the ServiceConnection
you can have two way communication and using startService()/stopService()
you can control it's lifetime.
The lifecycle image from the android site really explains it well:
By binding and starting the service you will get a service which can run indefinitely. The service will only stop if both of the following conditions are true:
- There are no clients bound to it.
- stopService() was called.
It requires a bit more maintenance but I found this to be the most reasonable option.
Ah, option (2) is probably what you want. You can override onStartCommand
to return START_STICKY
and the Service will continue to run after the Activity finishes.
When you bindService
you can get the actual Service instance back and then just invoke your custom methods on that as a way of communicating. Alternatively you could use one of the examples here
Binding with service will be the best way to do this.
Put this code in your activity onCreate and define your service with implementing onBind method returning the binder object. Define your IBinder properly in your service.
This will ensure service running all the time in the background. And every time your activity starts it will bind with the service. In the onDestroy() method of your activity unbind the service. Otherwise it will throw ServiceLeakedException.
YourService service;
ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder binderService) {
service = ((YourService.ServiceBinder)binderService).getService();
}
public void onServiceDisconnected(ComponentName name) {
}
};
// ... and bind.
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
On the basis of any calculation your service can launch your activity itself. As it get launched it will bind with the service. Then further communication can occur.
Hope it helps :)
精彩评论