2

I have a class that uses a class instance of import io.flutter.plugin.common.MethodChannel but now i want to pass that class instance to a Service where i can call it, but i cant get around it.

I have tried using putExtra but i cant seem to find a way to get it from the service end.

For example:

Intent playIntent = new Intent(activity.getApplicationContext(), MusicPlayerService.class);
playIntent.putExtra("activeAudioUrl", activeAudio);
playIntent.putExtra("channelInstance", channel);
activity.startService(playIntent);

Here is the service class from which i am trying to get the data:

public int onStartCommand(Intent intent, int flags, int startId) {
    String activeAudio = intent.getStringExtra("activeAudioUrl");
    MethodChannel methodChannel = intent.getParcelableExtra("channelInstance");

    ...
}
Fábio Nascimento
  • 2,644
  • 1
  • 21
  • 27
JBoy
  • 144
  • 2
  • 17
  • 6
    Basically if you want to pass a class in an intent, the class needs to implement the `Parcelable` interface. But, I doubt you want to pass an instance of `MethodChannel` in an intent. You will be leaking data associated to the channel. Why do you want to do that? – Leo May 03 '19 at 04:03
  • 1
    Does `MethodChannel` implements `Parcelable`? On the other hand you can bind Service and set the instance with `Binder`.. – ADM May 03 '19 at 04:04
  • no MethodChannel does not implement `Parcelable` – JBoy May 03 '19 at 04:18
  • 1
    How do i bind the service, please can you show a code sample. I'm new to java i am trying to create a plugin for a framework that needs to work with android. – JBoy May 03 '19 at 04:20
  • Maybe [this](https://stackoverflow.com/questions/55958561/how-to-navigate-to-another-page-but-show-information-according-to-the-items-on-m) method can solve your problem. – Devarsh Ranpara May 07 '19 at 07:14

2 Answers2

1

You should create a class containing your data to be passed and extend/implement that from Serializable or Parcelable and then you can put an object of that class as an Extra to your Intent and use it in your Service. In this class you creat your data, pass them and then retrieve them. For creating your custom Parcelable class you can see these following links:

1.stackoverflow

2.medium

And according to this link it's better to use Parcelable.

So, create a class that implement the Parcelable (e.g. name this class DataToSend), you can use constructor to pass your data and use getter for retrieving your data.

Edit => Now DataToSend is already implements Parcelable and all you have to do is :

Bundle bundle = new Bundle();
DataToSend dataToSend = new DataToSend(activeAudio, channel);
bundle.putParcelable("data", dataToSend);
Intent playIntent = new Intent(activity.getApplicationContext(), 
MusicPlayerService.class);
playIntent.putExtra(bundle);
activity.startService(playIntent);

and for retrieving data :

public int onStartCommand(Intent intent, int flags, int startId) {
    String activeAudio = intent.getStringExtra("activeAudioUrl");
    MethodChannel methodChannel = intent.getParcelableExtra("channelInstance");
    Bundle b = intent.getExtra();
    DataToSend data = (DataToSend) b.getParcelable("data");

    // Here you can retrieve your data(channel & activeAudio) from following
    // data object. (e.g. data.getAudio())
    ...
}
Amin Soheyli
  • 605
  • 2
  • 7
  • 16
0

You cannot pass non-data objects over an IPC boundary by calling startService(). What you are actually doing here is calling ActivityManager which is a system service running in a different process to start a service in your process for you. What you can do instead is put the MethodChannel reference in a place reachable both from the service and a place where you're starting it, for example by using dependency injection.