0

I guess I have more like a design issue than a "how to bind a service" issue. What I'm trying to do is to have a service running in a separate process that handles bluetooth communication. Further I have several tabs, within each another activity. The processing and UI events from each activity results in simple commands which have to be passed over bluetooth like "up", "down", "left" or "right". As the results in each tab activity are the same, I don't wnat to connect each with the service, and use the same message handler. So I created my own Handler object and a "connector" object. However I'm not sure how to connect this connector object with my service as it requries a context. Does it make sense to simply pass the application context to my connector object and bind it that way???

I'm open for any suggestions or hints

Alx
  • 5,995
  • 7
  • 30
  • 51

2 Answers2

0

I'd suggest against using binding in this case. Actually, I'd suggest against binding in most use cases. Try to handle all communication between you Activities and the service running in another thread using intents only.

That means: Send commands to the service from the activities by the .startActivity() method, passing the details of the actual command in the Intent's extras.

Receive events and result from the service in your activities by dynamically registered BroadcastReceivers. You register a listener in onResume() and unregister it in onPause() in you Activity. The service sends stuff only by broadcasting it (sendBroadcast()).

I prefer this architecture. It's loosely coupled and you can skip the annoying part where you're wondering if every one of your Activities unbinds correctly from you service when they're not using it. Also, you skip the pain of using IPC, which is a huge plus I think.

Zsombor Erdődy-Nagy
  • 16,546
  • 16
  • 74
  • 101
  • Hey Zsombor, sounds interesting, I've never used Broadcast receivers so far, do you have some hints for reading despite the API? – Alx Oct 23 '11 at 12:51
  • The official docs on BroadcastReceivers should be enough, they're quite simple to use actually. You just tell the system the types of intents your receiver should receive, and you write the callback (onReceive()) for your receiver that handles the intents, simple. – Zsombor Erdődy-Nagy Oct 23 '11 at 12:57
  • 1
    A drawback I have encountered with using BroadcastReceiver is that it is not allowed to bind to a service (and I think even calling a bound service method is not recomended). It only has 10 seconds to finish running. – mparaz Jun 09 '12 at 06:43
  • Indeed, this approach is not viable in all situations. – Zsombor Erdődy-Nagy Jun 09 '12 at 09:44
0

Here you are, my example .. will make you clear about that LOL

// My MyServiceInterface.aidl
package com.mad.exam;
interface MyServiceInterface{
     int getNumber();
}

//MyService 
public class MyService extends Service {

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    Toast.makeText(this, "Service OnBind()", Toast.LENGTH_LONG).show();
    return mBinder;
}

@Override
public void onCreate() {
    // TODO Auto-generated method stub
    super.onCreate();
    Toast.makeText(this, "Service Created", Toast.LENGTH_SHORT).show();
}

@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    Toast.makeText(this, "Service Destroyed ", Toast.LENGTH_SHORT).show();
}

@Override
public void onStart(Intent intent, int startId) {
    // TODO Auto-generated method stub
    super.onStart(intent, startId);
    Toast.makeText(this, "Service Started ", Toast.LENGTH_SHORT).show();
}

@Override
public boolean onUnbind(Intent intent) {
    // TODO Auto-generated method stub
    return super.onUnbind(intent);
}

private final MyServiceInterface.Stub mBinder = new MyServiceInterface.Stub() {
    public int getNumber() {
        return new Random().nextInt(100);
    }
};
}


//My Activity 
public class ServiceDemo extends Activity implements OnClickListener {
MyServiceInterface mService;
ServiceConnection mConnection;
Button retreive;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.service);
    retreive = (Button) findViewById(R.id.retreive);
    retreive.setOnClickListener(this);

    mConnection = new ServiceConnection() {

        public void onServiceDisconnected(ComponentName name) {
            // TODO Auto-generated method stub

        }

        public void onServiceConnected(ComponentName name, IBinder service) {
            // TODO Auto-generated method stub

            mService = MyServiceInterface.Stub.asInterface(service);

            try {
                int i;
                i = mService.getNumber();
                Toast.makeText(ServiceDemo.this, "The service value is: " + String.valueOf(i),
                        Toast.LENGTH_SHORT).show();
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };

}

public void onClick(View v) {
    // TODO Auto-generated method stub
    Log.i("My Tag", "Clicked");
    Button btn = (Button) v;
    Intent callService = new Intent(this, MyService.class);
    bindService(callService, mConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onStart() {
    // TODO Auto-generated method stub
    super.onStart();
    Intent callService = new Intent(this, MyService.class);
    bindService(callService, mConnection, Context.BIND_AUTO_CREATE);

}

}

George Nguyen
  • 2,179
  • 1
  • 15
  • 7
  • Welcome to Stack Overflow! Be careful when posting copy and paste boilerplate/verbatim answers to multiple questions, these tend to be flagged as "spammy" by the community. e.g.: http://stackoverflow.com/questions/6399274/android-local-service-sample-bindservice-and-serviceconnection/8019267#8019267 – Kev Nov 05 '11 at 13:34