1

I am having a problem with my Android service and client apps who rebind to it. Everything works fine when a client app initially binds to my service, after which messages can be sent from service to client. However, if the client app is killed and then binds agains, onRebind() is correctly called in the service, but my messenger in the intent is invalid, causing a DeadObjectException, as noted in the code below. Any ideas?

Here is my code for the service:

@Override
public IBinder onBind(Intent intent)
{        
    getMessenger(intent);

    return _inputMessenger.getBinder();
}

@Override
public void onRebind(Intent intent)
{        
    getMessenger(intent);
}

@Override
public boolean onUnbind(Intent intent)
{                
    return true;
}

private void getMessenger(Intent intent)
{
    Bundle extras = intent.getExtras();

    if (extras != null)
    {
        // Get the messenger sent from the app.
        // This is handled correctly after onBind() and onRebind().
        _outputMessenger = (Messenger) extras.get("MESSENGER"); 
        Log.i(TAG, "Got messenger from app: " + _outputMessenger);           
    }
}

private void sendMessageToClient(String key, String value)
{   
    Message message = Message.obtain();
    Bundle bundle = new Bundle();
    bundle.putString(key, value);
    message.setData(bundle);

    try
    {
        _outputMessenger.send(message); // EXCEPTION OCCURS HERE AFTER onRebind()
    }
    catch (Exception ex)
    {
        Log.e(TAG, "_outputMessenger.send() failed: " + ex);
    }
}

And here is the code for the application:

     Intent intent = new Intent("com.foobar.service");

    // Create a new messenger for the communication from service to app.
    _messenger = new Messenger(new ServiceToActivityHandler());
    intent.putExtra("MESSENGER", _messenger);

    _serviceConnection = new MyServiceConnection();

    _isBoundToService = _context.bindService(intent, 
                                           _serviceConnection, 
                                           Context.BIND_AUTO_CREATE);
stackoverflowuser2010
  • 38,621
  • 48
  • 169
  • 217

1 Answers1

0

There is a note on bound services... The part under additional notes should be useful. I think trapping the exception is probably what you should do...

try {
    // Do stuff
} catch(DeadObjectException e){
    // Dead object
}

I read that object lifetimes should be reference counted by android across processes, so you should be OK, when the client dies I wonder if

 _outputMessenger // needs to be unassigned in your service...?

I assume what is happening is that your binding to the service, it's pumping some data back to your client, your client goes away, the service continues running but then needs to pump some data to the client which has gone by this point?

Also this link

Community
  • 1
  • 1
0909EM
  • 4,761
  • 3
  • 29
  • 40
  • "the service continues running but then needs to pump some data to the client which has gone by this point". Yes, that is what is happening; the service is using a messenger that is no longer valid. But shouldn't the onRebind() and my getMessenger() method be able to use a new valid messenger? – stackoverflowuser2010 Aug 27 '12 at 22:01
  • I'm wondering if your unbinding the previous messenger...? Tho I'm not sure if you have to... You should be able to trap the exception and debug... Yes you should be able to rebind to the service as far as I know. Does the service restart (see logcat) [THIS](http://stackoverflow.com/questions/4300291/example-communication-between-activity-and-service-using-messaging) s/o topic might provide more info/ a starting point to help you resolve... – 0909EM Aug 27 '12 at 22:10
  • Alternatively can you not just communicate via intents? It might make your code easier...? – 0909EM Aug 27 '12 at 22:11
  • "But shouldn't the onRebind() and my getMessenger() method be able to use a new valid messenger?" Answer: no. The intent in onRebind is the original one, from the first bind. You'll get the same old Messenger. – ecdpalma Apr 24 '13 at 14:33