1

It's my first question on SO, I hope this question won't be bad.

I have a service, it starts working when user launchs an app and works until user will kill it via task killer or turn off his device.

This service has a background thread which does some work with data. I need to bind activities (from activities, not by service) and sometimes (1-2 times per 30 seconds) send data to binded activities.

Structure of my service:

public class myserv extends Service {
  public static boolean started=false;
  public class workwithdata extends Thread {
    @Override
    public synchronized void start() {
      super.start();
      //.. Not important.
    }
    @Override
    public void run() {
      if (running) return;
      while (true) {
        if(condition) mythread.sleep(30000);
        else {
          Object data = recieveMyData();
          if (!data.isEmpty()) {
            //.. Some work with recieved data, not important.
            sendDataToBindedActivities(data); //This is what I need.
          }
          mythread.sleep(10000);
        }
      }
    }
  }
  @Override
  public void onCreate() {
    super.onCreate();
    this.started=true;
    mythread = new workwithdata();
    mythread.start();
  }
}

Well, I found one question but my problem has a little differences: I don't need to send any data to the service, I need just send some data to all binded activities (which service doesn't know at all).

Structure for which I'm looking for:

public class myact extends Activity {
  @Override
  public void onCreate(Bundle bun) {
    super.onCreate(bun);
    if(!myserv.started) {
      Intent service = new Intent(getApplicationContext(), myserv.class);
      getApplicationContext().startService(service);
    }
    bindToService(this);
  }
  @Override
  public void onRecievedData(Object data) {
    //work with recieved data from service "myserv".
  }
}

I also tried to find some solutions in android documentation but I didn't find what I need.

So, main question is: is it possible to work with communications from service to activities?. If no: What should I use for this purpose? If yes, just, sorry, can I ask for some code or class names, because I tried to find and didn't...

Thank you.

Community
  • 1
  • 1

1 Answers1

0

You need to use a RemoteCallbackList

When your clients bind to the service, you will need to register them using RemoteCallbackList.register().

When you want to send data to the bound clients, you do something like this:

int count = callbackList.beginBroadcast();
for (int i = 0; i < count; i++) {
    try {
        IMyServiceCallback client = callbackList.getBroadcastItem(i);
        client.onRecievedData(theData); // Here you callback the bound client's method
                                  //  onRecievedData() and pass "theData" back
    } catch (RemoteException e) {
        // We can safely ignore this exception. The RemoteCallbackList will take care
        //  of removing the dead object for us.
    } catch (Exception e) {
        // Not much we can do here except log it
        Log.e("while calling back remote client", e);
    }
}
callbackList.finishBroadcast();

An example can be found here It is kinda complicated, but maybe you don't need everything this offers. In any case, have a look.

David Wasser
  • 93,459
  • 16
  • 209
  • 274
  • Is this possible to deny to bind not app's activities to my service? – Matvey Filatov Jun 07 '12 at 08:04
  • Yes. You can prevent other application's access to your service using in the tag in the manifest. – David Wasser Jun 07 '12 at 10:56
  • I've implemented it via `SharedPreferences.OnSharedPreferenceChangeListener` and a few handlers. Is it bad? (I don't know but it works normally) – Matvey Filatov Jun 11 '12 at 07:14
  • You can also do it that way. As long as your data isn't too big and it can easily be stored in SharedPreferences (ie: just simple primitives). Also, be aware that this gets complicated if your service is remote and runs in another process. – David Wasser Jun 11 '12 at 07:19
  • Yes, it runs on another process. But I made a few handlers with which it works normally. – Matvey Filatov Jun 11 '12 at 07:26
  • I can only tell you that in some Android versions (especially 2.3), writing preferences in one process and reading them from another is **not** reliable. It should work better as of 3.x if you make sure to specify `MODE_MULTI_PROCESS` when calling `getSharedPreferences()`. – David Wasser Jun 11 '12 at 07:32
  • Yes, in 2.2 it should work even without specifying `MODE_MULTI_PROCESS` because that is the default behaviour. But, if you don't specify `MODE_MULTI_PROCESS` then it will **not** work in later versions, unless you are targeting 2.2 or less with – David Wasser Jun 11 '12 at 09:05