Friday, August 23, 2013

[android-developers] Lightweight communication from Local Service to Activity

I haven't seen this done anywhere, so I suspect there is something wrong with it.  It is too simple, compared to the more complicated Messenger methods.  The idea is to get a very lightweight communication between a Local Service (part of my app) and an activity.  Calling methods or reading members of the Service is easy.  You just do this in the activity:

/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName className,
            IBinder service) {
        // We've bound to LocalService, cast the IBinder and get BTService instance
        MyBtServiceBinder binder = (MyBtServiceBinder) service;
        btserv = binder.getService();
        mBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
};

public void onResume()
{
    super.onResume();
    // Bind to LocalService
    Intent intent = new Intent(this, BTService.class);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    startService(intent);
}
Then do this in the Service:

    private final IBinder mBinder = new MyBtServiceBinder();
  . . .
@Override
public IBinder onBind(Intent arg0) {
    return mBinder;
}

public class MyBtServiceBinder extends Binder {
    BTService getService() {
      return BTService.this;
    }
}

(My service is called BTService.)   Now from my activity I can access any method in the service by "btserv", a reference to the service.  But I am thinking now about the other way around.  Suppose I have an event in my service where I want to trigger some action back in the activity.  As I said earlier, I know there are heavyweight methods involving the Messenger class where this can be done.  But I tried this instead:

My service has a member called "main" that holds a reference to a Main activity.  It is public, so I can set it from my activity as follows:


    public void onServiceConnected(ComponentName className,
            IBinder service) {
        MyBtServiceBinder binder = (MyBtServiceBinder) service;
        btserv = binder.getService();
        mBound = true;
        btserv.main = Main.this;   //  <--- Give service a reference to current activity
    }

public void onPause()
{
    super.onPause();
    if (mBound) {
        btserv.main = null;  //  <---- invalidate reference to activity
        unbindService(mConnection);
        mBound = false;
    }
And then in my service I use that reference to post to a handler:

        if(main != null)
        {
            main.handler.post(main.doEventFromService);
        }
where doEventFromService is a Runnable in my main activity.  And my preliminary testing indicates this works.  But perhaps it is risky.  I took great pains to ensure that "main" is only non-null when my activity is in the foreground.  If I mess up there it is possible that my service might be posting to an activity that no longer exists.  Or is that protected anyway through the mechanism of handlers?

The code doing the posting from the service is not in some worker thread.  It is in the same UI thread that is running the activity.  So that should be safe, right?  I would appreciate any comments on possible dangers of this seemingly easy way to trigger an event from a service.



--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
---
You received this message because you are subscribed to the Google Groups "Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-developers+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home


Real Estate