0

I have one method that returns a BufferedReader from which my App is getting the output of another program.

In Manager.java

public BufferedReader start() {
    String[] commandLine2 = { "/system/bin/sh", "/system/app/launcher.sh" };

    Process process = null;

    try {
        process = Runtime.getRuntime().exec(commandLine2);
        reader = new BufferedReader(new InputStreamReader(
                process.getInputStream()));
        writer = new OutputStreamWriter(process.getOutputStream());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return reader;
}

In my MainActivity I use: outputReader = manager.start(); where outputReader is a private instance of BufferedReader and manager is one of Manager.

As long as I use this Buffered reader in an AsyncTask inside MainActivity.java everything goes ok since my BufferedReader is visible in its scope but when I want to use a Service to accomplish the task I have some troubles.

There is no way to use a Intent.putExtra(Object) with objects which are neither Serializable nor Parcelable (and my BufferedReader is not).

How can I pass my BufferedReader to a Service then?

Darshan Kunjadiya
  • 3,323
  • 1
  • 29
  • 31
Cob013
  • 1,057
  • 9
  • 22
  • Can't you just expose a public method on your service and pass it to that? eg `setReader()`. See here: http://stackoverflow.com/questions/2272378/android-using-method-from-a-service-in-an-activity – Ken Wolf Jun 28 '13 at 13:06
  • In my MainActivity I use this code to start the Service: `Intent service = new Intent(getApplicationContext(),ReaderService.class); startService(service);` how could I use a `setReader()` method in this case? Of course it would be useful and sufficient to have such a method – Cob013 Jun 28 '13 at 13:12
  • 1
    Without knowing your architecture or service I would say a bound service would be better - then you basically have a reference to your service in your activity that you *can call public methods on*. Look at the IBinder example here: http://stackoverflow.com/a/10799514/833647 – Ken Wolf Jun 28 '13 at 13:15
  • I haven't used bound services yet and I've reached to fix my problem with those, thanks Ken. – Cob013 Jun 28 '13 at 14:29
  • I've added it as an answer for completeness :) – Ken Wolf Jun 28 '13 at 14:34

2 Answers2

1

I am passing only primitives with Intent.putExtra and only if they are a few. When I need more primitives I am declaring a DataTransferObjectOfMyType which hold together. That dto I am setting to a common place, like ApplicationContext in MyApplication class. On the new intent I am checking if there or not, and using it. Good or bad design I don't care. It is working. If all it matter for you too, than use this approach, because it is working :)

Btw: I wouldn't pass the Buffered reader, because than who knows when need to be closed. Instead of this I would pass all parameters, which needed to create a BufferedReader.

I hope it helps!

  • Thanks for your answer mathe, I'd have tried your approach (how can you save a DTO in your application context? using Bundle or SharedPreferences perhaps?) but Bound Services just made my day and I've learnt something new so, according to your advice, no matter what 'it's working' :D – Cob013 Jun 28 '13 at 14:32
  • @Rob013 The DTO is transferred with a setter and getter between Activityes, like a property. If needed to me made persinstent, than need to write his Serialization and Deserialization process. An advantage of this is: I know what is there, I have full access instead of a Buffered Reader os other complex system objects, which maybe has some fields which aren't serializable. A few times met those cases, and needed a lot of overrides and workarounds. This is easy working solution :) Easy to test, modify, and so on. Why to reinvent the wheel? :) –  Jun 28 '13 at 14:42
1

I would advise you to use a Bound Service

http://developer.android.com/guide/components/bound-services.html

A bound service is the server in a client-server interface. A bound service allows components (such as activities) to bind to the service, send requests, receive responses, and even perform interprocess communication (IPC)

Basically you can expose public methods on your service and call them. So in this instance you can create something like the following in your Service:

public void setReader(BufferedReader reader) {
    this.reader = reader;
    // do whatever you want with it in your service, etc.
}

and call it from your Activity.

For more details see this great post: Android - Using method from a Service in an Activity?

Community
  • 1
  • 1
Ken Wolf
  • 23,133
  • 6
  • 63
  • 84