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 [email protected]
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to