I’ve been thinking about this recently when implementing account authenticators with three-legged authorisation flows. Sending a result back to the service for processing performs better than processing it in the activity. It also provides a better separation of concerns.
It’s not that clearly documented, but Android provides an easy way to send and receive results anywhere (including services) with ResultReceiver.
I’ve found it to be a lot cleaner than passing activities around, since that always comes with the risk of leaking those activities. Additionally, calling concrete methods is less flexible.
To use ResultReceiver in a service, you’ll need to subclass it and provide a way to process the received result, usually in an inner class:
public class SomeService extends Service {
    /**
     * Code for a successful result, mirrors {@link Activity.RESULT_OK}.
     */
    public static final int RESULT_OK = -1;
    /**
     * Key used in the intent extras for the result receiver.
     */
    public static final String KEY_RECEIVER = "KEY_RECEIVER";
    /**
     * Key used in the result bundle for the message.
     */
    public static final String KEY_MESSAGE = "KEY_MESSAGE";
    // ...
    /**
     * Used by an activity to send a result back to our service.
     */
    class MessageReceiver extends ResultReceiver {
        public MessageReceiver() {
            // Pass in a handler or null if you don't care about the thread
            // on which your code is executed.
            super(null);
        }
        /**
         * Called when there's a result available.
         */
        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            // Define and handle your own result codes
            if (resultCode != RESULT_OK) {
                return;
            }
            // Let's assume that a successful result includes a message.
            String message = resultData.getString(KEY_MESSAGE);
            // Now you can do something with it.
        }
    }
}
When you start an activity in the service, create a result receiver and pack it into the intent extras:
/**
 * Starts an activity for retrieving a message.
 */
private void startMessageActivity() {
    Intent intent = new Intent(this, MessageActivity.class);
    // Pack the parcelable receiver into the intent extras so the
    // activity can access it.
    intent.putExtra(KEY_RECEIVER, new MessageReceiver());
    startActivity(intent);
}
And finally, in the activity, unpack the receiver and use ResultReceiver#send(int, Bundle) to send a result back.
You can send a result at any time, but here I've chosen to do it before finishing:
public class MessageActivity extends Activity {
    // ...
    @Override
    public void finish() {
        // Unpack the receiver.
        ResultReceiver receiver =
                getIntent().getParcelableExtra(SomeService.KEY_RECEIVER);
        Bundle resultData = new Bundle();
        resultData.putString(SomeService.KEY_MESSAGE, "Hello world!");
        receiver.send(SomeService.RESULT_OK, resultData);
        super.finish();
    }
}