Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API redesign - feedback needed #86

Closed
ryanheise opened this issue Sep 23, 2019 · 7 comments
Closed

API redesign - feedback needed #86

ryanheise opened this issue Sep 23, 2019 · 7 comments
Assignees
Labels
help wanted Extra attention is needed

Comments

@ryanheise
Copy link
Owner

Hi all. I'd like to do a quick poll on a proposed API change for the background task. This is motivated by some recent changes to Flutter's background Dart execution API, but what I have in mind may also just generally simplify the API.

Currently, the background task must call:

  AudioServiceBackground.run(
    onStart: () {},
    onPlay: () {},
    onPause: () {},
    onStop: () {},
    onClick: (MediaButton button) => {},
  );

The run() method initialises the plugin, and this really should be the first method that you call within the background task. The problem is that in order to implement the various callbacks above, you need some shared state which needs to be created before run() is invoked, like this:

final player = CustomAudioPlayer();
AudioServiceBackground.run(
  ...
  onPlay: player.play,
  onStop: player.stop,
  ...
);

This means that in practice, run() isn't actually the first method called, and at least on the flutter dev channel, initialisation doesn't complete successfully. So below are the alternative proposals:

Option 1

Just insert an init method that you should call first, like this:

AudioServiceBackground.init();
final player = CustomAudioPlayer()
AudioServiceBackground.run(...

Option 2

Change the argument of run() to be a builder:

AudioServiceBackground.run(() => CustomAudioPlayer());

And, redefine CustomAudioPlayer so that it implements a new interface BackgroundAudioTask and overrides the callbacks it needs, rather than the old style of composition. I originally went for composition since this seemed to be encouraged in the Flutter framework, but now that the project is more mature, it's clearer that inheritance probably solves the problem better. The interface would look like this:

abstract class BackgroundAudioTask {
  Future<void> onStart();
  void onStop();
  void onPlay() {}
  void onPause() {}
  ...
}

Option 3

Following on from Option 2, we can go one step further and completely eliminate the AudioServiceBackground API which is a static-based API and replace it by BackgroundAudioTask which is instantiated, and where the constructor of this class serves the purpose of initialising the plugin. All of the static methods currently in AudioServiceBackground can now be inherited by the BackgroundAudioTask subclass. So now, your background task entrypoint would look like this:

CustomAudioPlayer();

Where this class extends BackgroundAudioTask and calls the super constructor, and provides overrides of the desired callbacks.

This is attractive in its simplicity, although unlike Option 2, it is theoretically possible for someone to write code in the initialiser list of their subclass constructor that tries to load other plugins before super() has had a chance to fully initialise things. But maybe that can just be addressed by documentation, and anyway, it is possible for a programmer to misuse the plugin in other ways (e.g. by inserting code above the one line above).

My thoughts

Here I'll try to taint the results of the poll ;-) I'd prefer Option 2 or Option 3 since Option 1 keeps around an old problem we've had where you have to implement all of the callbacks in the run() method which just redirect to some other custom class, and then define all of those callback headers again, which seems like a redundant step when this is the most common way that people will actually use the plugin.

@ryanheise ryanheise added the help wanted Extra attention is needed label Sep 23, 2019
@hacker1024
Copy link
Contributor

Thanks for asking for our feedback.
I like option 2 the best. I like the inheritance structure better than having everything in a function call, like in option 1. I don't like option 3 because I don't think a major background task like this should be started just by instantiating an object - it's not that clear that you're starting the task.

@ryanheise
Copy link
Owner Author

Thanks @hacker1024 , that sounds reasonable.

Happy to hear any more thoughts @rohansohonee , @itog , @Dekkee , @BeMacized , @alexelisenko

Otherwise I'll go ahead with Option 2.

@Dekkee
Copy link

Dekkee commented Sep 24, 2019

Well. It looks like i didnt face your problems or just used lib in wrong way. Anyway first variant is worse due to more complexity with new method that could be redundant (in my case). Third seems nice because it eliminates entity that you should worry about. But it cant beat the second one because of its extensibility.
So we have two cases.

  1. Inherit BackgroundAudioTask and your player will work out of the box with background processing like on ios.
  2. Get any of your favorite player, implement interface. Profit.

Well. I’ll vote for second.

@alexelisenko
Copy link

@ryanheise Option 2 seems to be reasonable

@ryanheise
Copy link
Owner Author

Thanks to everyone for weighing in! I've implemented Option 2 based on the consensus and committed (f5d828e). Assuming nobody finds any problems, I'll release this to pub.dev tomorrow with an appropriate semantic version to indicate the breaking change.

@ryanheise
Copy link
Owner Author

Version 0.4.0 is now published on pub.dev.

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs, or use StackOverflow if you need help with audio_service.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 23, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants