ServiceConnection为什么没有回调?
Android
public abstract boolean bindService(@RequiresPermission Intent service,
@NonNull ServiceConnection conn, @BindServiceFlags int flags);
绑定服务,有时候 conn的callback 没有调用,为啥?
bindService 返回值
bindService 本身是有返回值的,如果返回false,肯定是没有返回值的。
另外:
1.有的习惯是bindService之前先startService。其实这步完全没有必要,bindservice本身就会启动service,而且优先级会更高。startservice在高版本Android还会抛异常,因为没有权限。
2.有的时候,需要同步等待conn的返回,但是默认回调是在主线程,如果在主线程调用等待会直接卡死。所以注意这样操作需要切换线程。
3.针对上面的那个情况,新版本Android提供了一个新的方法:
public boolean bindService(@RequiresPermission @NonNull Intent service,
@BindServiceFlags int flags, @NonNull @CallbackExecutor Executor executor,
@NonNull ServiceConnection conn)
Service#onBind 返回
如果onBind 返回的是null,也会导致conn 没有回调的。
这就是为什么onServiceConnected 不需要判空的原因,被系统拦截了。
在哪里拦截呢?
if (mPackageInfo != null) {
if (executor != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
} else {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
}
} else {
throw new RuntimeException("Not supported in system context");
}
bind的时候,conn会被包装掉。这里也看到了新的参数:executor。返回的是:ServiceDispatcher。
public void doConnected(ComponentName name, IBinder service, boolean dead) {
ServiceDispatcher.ConnectionInfo old;
ServiceDispatcher.ConnectionInfo info;
.........//省略
// If there was an old service, it is now disconnected.
if (old != null) {
mConnection.onServiceDisconnected(name);
}
if (dead) {
mConnection.onBindingDied(name);
} else {
// If there is a new viable service, it is now connected.
if (service != null) {//必须不为空才走回调
mConnection.onServiceConnected(name, service);
} else {
// The binding machinery worked, but the remote returned null from onBind().
mConnection.onNullBinding(name);
}
}
}
这里就能看出来。
顺便再说一点:我之前想在onBind里面做调用权限检查,没有自定义权限的就不给返回。但是这是不行的。因为onBind的真实调用是app本身,所以千万别这么做。