开发者

Defensive code for controlling a service

开发者 https://www.devze.com 2023-04-10 07:34 出处:网络
I\'m trying to revamp my multi-activity app to use just once instance of a LocationListener which I intend to implement in a service. Prior to doing this I\'ve been experimenting with a stub activity

I'm trying to revamp my multi-activity app to use just once instance of a LocationListener which I intend to implement in a service. Prior to doing this I've been experimenting with a stub activity and a stub service to see what happens under error conditions.

I want to see what happens if I attempt to unbind from a service which has already been unbound and avoid any errors if this should happen. The activity has two buttons to bind/unbind. If I deliberately hit the unbind twice in succession I do get a runtime error.

What condition can I test for at the point marked '<<<<<' in the code below to skip calling unbind again?

My activity code is

public void myClickHandler(View target) {
    switch (target.getId()) {
    case R.id.bind:
        Log.d("STAG", "Activity One pressed BIND button");
        mServiceConnected = bindService(new Intent(
                "com.nbt.servicetest.LOCATIONSERVICE"), mServconn,
                Context.BIND_AUTO_CREATE);
        break;
    case R.id.unbind:
        Log.d("STAG", "Activity One pressed UNBIND button");
        try{
        if (mServconn != null) // <<<< What to put here if already unbound?
            unbindService(mServconn);}
        catch(Exception e){
            Log.d("STAG", "Exception " + e.getMessage());
        }
        break;
    }
}

ServiceConnection mServconn = new ServiceConnection()开发者_开发问答 {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        Log.d("STAG", "Activity One service connected");
        mIbinder = service;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        Log.d("STAG", "Activity One service disconnected");
    }
};

The service is starting/stopping OK. I've put log lines in the service code with the same tag on all the pertinent lines. The output is :

STAG(2945): Activity One onCreate
STAG(2945): Activity One onStart
STAG(2945): Activity One onResume
STAG(2945): Activity One pressed BIND button
STAG(2945): Loc service ONCREATE
STAG(2945): Loc service ONBIND
STAG(2945): Activity One service connected
STAG(2945): Activity One pressed UNBIND button
STAG(2945): Loc service ONUNBIND
STAG(2945): Loc service ONDESTROY
STAG(2945): Activity One pressed UNBIND button
STAG(2945): Exception Service not registered: com.nbt.servicetest.ServiceTesterActivityOne$1@43b8b290

I note that the activity's onServiceDisconnected() never gets called, is this normal?


The simplest thing to do would be to introduce another variable, say, isServConnBound, and add checks on both bind and unbind actions. Of course, remember to update the variable after you call bindService and unbindService.


I agree with vhallac - just use boolean flags. What are your concerns with this approach? As for me there's nothing to be afraid of.

As to why "the activity's onServiceDisconnected() never gets called" - yes, this is normal. Look what API says on this callback:

Called when a connection to the Service has been lost. This typically happens when the process hosting the service has crashed or been killed.

Your process has neither crashed nor been killed, so this is an expected behavior. Even more, since you have your service in the same process, you'll never get this called. This is important when you bind to a service that runs in another process (inter process communication).

0

精彩评论

暂无评论...
验证码 换一张
取 消