Android java.lang.IllegalArgumentException:服务未注册

dco*_*cow 37 android android-service android-service-binding

我有一个看起来像这样的设置:

class MyFragment implements SomeEventListener {

    Application mAppContext;    

    boolean mBound;
    boolean mDidCallUnbind;
    MyIBinder mBinder;
    ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mBound = true;
            mBinder = (MyIBinder) service;
            mBinder.getThings();...
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mDidCallUnbind = false;
            mBound = false;
            mBinder = null;
        }
    };

    ...

    @Override
    public void onSomeEvent() {
        mAppContext.bindService(...);
    }

    void unbindService() {
        if (mBound && !mDidCallUnbind) {
            mDidCallUnbind = true;
            mAppContext.unbindService(mConnection);
        }
    }

    @Override
    public void onPause() {
        unbindService();
        super.onPause();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我仍然不时地看到标题中的错误:java.lang.IllegalArgumentException: Service not registeredunbindService()调用时生成.我错过了一些愚蠢的事情,还是有更多的事情发生?我应该注意到,这个片段可能不止一个存在.

编辑

由于似乎没有人真正阅读代码,让我解释一下. unbindService()不会调用,Context.unbindService(ServiceConnection)除非服务绑定(mBound)并且之前没有调用它之前onServiceDisconnected(...)从可能的先前调用中回拨unbindService().

请记住,在任何情况下,Android都会解除您的服务绑定,使服务不受约束,但不会调用onServiceDisconnected,从而使我处于陈旧状态?

另外,我正在使用我的Application上下文来进行初始绑定.假设像:

@Override
public void onCreate() {
    mApplication = getContext().getApplicationContext();
}
Run Code Online (Sandbox Code Playgroud)

Jac*_*ips 25

mIsBound在内部使用doBindService()doUnbindService()不是在ServiceConnection实例中使用.

ServiceConnection mConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        mBinder = (MyIBinder) service;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        mBinder = null;
    }
}; 

...

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

public void doUnbindService() {
    if (mIsBound) {
        unbindService(mConnection);
        mIsBound = false;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是在http://developer.android.com/reference/android/app/Service.html中完成的

  • @likejiujitsu bindService方法的文档状态:`如果已成功绑定到服务,则返回true; 如果未建立连接,则返回false,因此您将不会收到服务对象.但是,您仍然应该调用unbindService(ServiceConnection)来释放连接.换句话说,只要方法返回就会建立连接,因此在调用此方法之后,您必须解除绑定服务. (6认同)
  • 没有意义.你在*它实际绑定之前设置mIsBound*?我相信bindService在另一个线程上. (5认同)

aar*_*gas 17

我意识到这个问题已经得到了回答.但我认为有理由深入了解人们犯这个错误的原因.

问题实际上是培训文档.http://developer.android.com/reference/android/app/Service.html显示正确的实施,而"ActivityMessenger"中的https://developer.android.com/guide/components/bound-services.html显示了非常不正当的实施.

在"ActivityMessenger"示例中,可能会在服务实际绑定之前调用onStop().

这种混淆的原因是它们使用绑定服务布尔值来表示不同示例中的不同内容.(主要是被称为OR的bindService()实际连接的服务)

在正确的示例中,unbind()基于绑定的布尔值完成,绑定的布尔值表示调用bindService().由于它排队等待主线程执行,因此无论何时(如果有)onServiceConnected()发生,都需要调用unbindService()(因此排队等待执行).

在其他示例中,例如http://developer.android.com/reference/android/app/Service.html中的示例.绑定表示服务实际上已绑定,因此您可以使用它而不会获得NullPointerException.请注意,在此示例中,仍然进行unbindService()调用,并且绑定的布尔值不确定是否取消绑定.

  • 我知道我已经看过两种方式,但是不记得错误信息是从哪里来的...感谢建立连接。 (2认同)

pel*_*lus 8

java.lang.IllegalArgumentException: Service not registered意味着您在unbindService()被叫时没有受到服务的约束.

所以你的情况,onSomeEvent()调用之前从来没有叫unbindService()onPause()


小智 6

此异常的另一个可能原因可能unbindService是由错误的Context. 因为服务不仅可以被活动绑定,还可以被其他继承的实例Context(除了广播接收器),甚至被其他服务unbindService绑定,请确保由绑定了Service而不是由绑定Service本身的上下文调用。这将直接产生上述异常“服务未注册”。


wuk*_*ong 6

就我而言,我使用调用了bindServiceActivity Context并尝试使用ApplicationContext. 不要这样做。


Roh*_*ngh 5

原因?

如果在您的活动中, unbindService() 在 bindService() 之前被调用,那么您将得到 this IllegalArgumentException

如何避免?
这很简单。如果按此顺序绑定和取消绑定服务,则不需要布尔标志。

解决方案1:

绑定onStart()和解绑onStop()

Your Activity {

    @Override
    public void onStart()
    {
        super.onStart();
        bindService(intent, mConnection , Context.BIND_AUTO_CREATE);
    }

    @Override
    public void onStop()
    {
        super.onStop();
        unbindService(mConnection);
    }

 } 
Run Code Online (Sandbox Code Playgroud)

解决方案2:
绑定onCreate()和取消绑定onDestroy()

 Your Activity {

    @Override
    public void onCreate(Bindle sis)
    {
        super.onCreate(sis);
        ....
        bindService(intent, mConnection , Context.BIND_AUTO_CREATE);
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        unbindService(mConnection);
    }         

 }
Run Code Online (Sandbox Code Playgroud)

相关链接:

Android的官方文件表明
如果你需要互动与服务只在您的活动是可见的,然后一起去解决方法1
如果您希望您的活动即使在后台停止时也能收到响应,请使用Solution2