Doubts about bindService
Asked Answered
K

2

3

I have some boubts about Android bound service. The guide: http://developer.android.com/guide/components/bound-services.html ,about bindService(), says:

The `bindService()` method returns immediately without a value

But this does not seems to be correct, since here the signature of the method is

public abstract boolean bindService (Intent service, ServiceConnection conn, int flags)

where the returned boolean value is described as below:

If you have successfully bound to the service, true is returned; false is returned if the connection is not made so you will not receive the service object.

So the question is: why the documentation says that the method returns immediately without a value? Moreover, here, the bind is done in this way:

void doBindService() {
    bindService(new Intent(Binding.this, 
            LocalService.class), mConnection, Context.BIND_AUTO_CREATE);
    mIsBound = true;
}

and I don't understand the sense of mIsBound = true, since the javadoc says that bindService() can also return false, if the bounding to service fail. So it should be:

void doBindService() {
    mIsBound = bindService(new Intent(Binding.this, 
            LocalService.class), mConnection, Context.BIND_AUTO_CREATE);
}

Am I wrong?

Koeppel answered 30/9, 2014 at 17:58 Comment(6)
the returned value has little sense imho, for example if your service is not already running and you bind to it with flags == 0 the returned value is true, why? i have no idea...Matlick
Yes, it is contradictory, since we can be know if the connection is created or not, only when onServiceConnect() is called, and not immediately.Koeppel
its worse: your bindService() returns true but onServiceConnected() is never called (the case when service is not started/created and flags == 0), i think you can simply forget about the returned value and rely on ServiceConnection onlyMatlick
Right. In fact my idea is to set a mIsBound inside the onServiceConnected(), lettig it as default as false, so if onServiceConnected() is never called the variable remains false.Koeppel
I am with @Matlick on this one in regards to ignoring the returned boolean. I almost feel like they left the boolean return in there on accident and meant to follow the void convention mentioned in the documentation. The boolean can be misleading at best, again as pskink mentionedCavesson
After further investigation into the bound-services link you posted it appears that even they handle the connection status with a boolean that is directly managed within the service connection methods. Seems like the way to go.Cavesson
M
6

The documentation is incorrect. When returned boolean is false this means that no further attempts to establish connection are made. When true is returned this means that system tries to establish a connection and this can succeed or fail.

Look at answer for this question: "in what case does bindservice return false". Basically bindservice returns false when it does not find a service to even attempt to bind to.

Magee answered 30/9, 2014 at 18:30 Comment(0)
E
0

Ok, i finally completed learning all the nuances of binding services in android, and that is the ServiceBindHelper class, that can be treated as "ultimate truth" (excuse my immodesty).

https://gist.github.com/attacco/987c55556a2275f62a16

Usage example:

class MyActivity extends Activity {
    private ServiceBindHelper<MyService> myServiceHelper;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        myServiceHelper = new ServiceBindHelper<MyService>(this) {
            @Override
            protected Intent createBindIntent() {
                return new Intent(MyActivity.this, MyService.class);
            }

            @Override
            protected MyService onServiceConnected(ComponentName name, IBinder service) {
                // assume, that MyService is just a simple local service
                return (MyService) service;
            }
        };
        myServiceHelper.bind();
    }

    protected void onDestroy() {
        super.onDestroy();
        myServiceHelper.unbind();
    }

    protected void onStart() {
        super.onStart();
        if (myServiceHelper.getService() != null) {
            myServiceHelper.getService().doSmth();
        }
    }
}
Existential answered 4/1, 2016 at 23:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.