Communicate with Activity from Service (LocalServi

2019-01-13 22:15发布

问题:

Common scenario - Activity with a background Service to poll server.

The Service will run periodically via AlarmManager and also perform tasks for the Activity (user hits a button, go fetch something from server).

I'd like to know the best practices here. I think the best design would be the Android LocalService example: http://developer.android.com/reference/android/app/Service.html#LocalServiceSample

However in the example the Activity has a reference to the activity mBoundService but there is no reverse connection (the Service has no way to call the Activity).

What is the best way for the Service to call the Activity?

Do I use Intents, BroadcastReceivers, Messages? How?

回答1:

I think the best design would be the Android LocalService example: http://developer.android.com/reference/android/app/Service.html#LocalServiceSample

I wouldn't. Use the loosest possible coupling you can stand. Hence, on average, aim for the command pattern with startService() instead of the binding pattern with bindService(). Notably, binding is a bit of a pain when it comes to dealing with configuration changes (e.g., screen rotations).

What is the best way for the Service to call the Activity? Do I use Intents, BroadcastReceivers, Messages? How?

See Notify activity from service



回答2:

If you need tight coupling between your activity using bindService(), the way you communicate depends on who is originating the communication.

If the Service is originating (due to say an Alarm that has some new information to share), it would typically send a broadcast.

If the Activity is originating (due to say your example "go fetch something from server"), it could be handled asynchronously using AsyncTask or similar. That is, you could fetch from the server in the AsyncTask.doInBackground(), and post the results back to the activity in AsyncTask.onPostExecute. This scenario be a bit more complicated if the requested operation is expected to take a very long time - in which case I would de-couple it, and send a broadcast back from the Service instead.



回答3:

As written here

When you want to communicate from service to an Activity or Fragment which did NOT started the service or to communicate from service to multiple activities/fragments then you can use Event Bus or Broadcast Intents since they can receive callback for an event in any activity or fragment wherever they are implemented.If you want to communicate from service to an activity/fragment which started the service then you can use Pending Intent or Messenger as they can be put into an Intent extra and passed to Service.

Pending Intent

We can use createPendingResult() which creates a new PendingIntent object which you can hand to service to use and to send result data back to your activity inside onActivityResult(int, int, Intent) callback.

Event Bus

You can have the service raise events which activities or fragments can listen for and respond to using Event Bus.

Messenger

Messenger is parcelable ,and can therefore be put into an Intent extra,so your activity can pass this Messenger to the service.Service will populate Message object with whatever data needs to be send.

Broadcast Intents

Service can send a broadcast which can be responded by the activity.