ServiceConnection没有回调的一次排查记录

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本身,所以千万别这么做。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值