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 registered在unbindService()调用时生成.我错过了一些愚蠢的事情,还是有更多的事情发生?我应该注意到,这个片段可能不止一个存在.
编辑
由于似乎没有人真正阅读代码,让我解释一下. 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中完成的
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()调用,并且绑定的布尔值不确定是否取消绑定.
java.lang.IllegalArgumentException: Service not registered意味着您在unbindService()被叫时没有受到服务的约束.
所以你的情况,onSomeEvent()调用之前从来没有叫unbindService()的onPause()
小智 6
此异常的另一个可能原因可能unbindService是由错误的Context. 因为服务不仅可以被活动绑定,还可以被其他继承的实例Context(除了广播接收器),甚至被其他服务unbindService绑定,请确保由绑定了Service而不是由绑定Service本身的上下文调用。这将直接产生上述异常“服务未注册”。
如果在您的活动中, 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。
| 归档时间: |
|
| 查看次数: |
34422 次 |
| 最近记录: |