踩坑之_绑定远程服务

当需要进程间通信的时候有时候需要用到aidl技术,此时就需要绑定远程的服务

具体如何使用aidl技术,在此处不做介绍,只是说说在开发中在绑定过程中遇到的坑

不多说直接上代码:

 	 Intent intent = new Intent();
        intent.setAction("wsls.MyService");//通过隐式意图启动远程服务
        mConn = new MyServiceConnection();
        bindService(intent, mConn, Context.BIND_AUTO_CREATE)
   private class MyServiceConnection implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
          //绑定成功回调,返回绑定的IBinder对象
          
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
           //远程服务断开连接(比如远程服务挂掉了)
        }
    }



次方法在4.4及以下没有问题,能够正常绑定,但运行在5.0之后会报以下异常

Caused by: java.lang.IllegalArgumentException: Service Intent must be explicit

于是开始查看源码,点击bindService方法,跳转到

ContextWrapper类中的
@Override
public boolean bindService(Intent service, ServiceConnection conn,
        int flags) {
    return mBase.bindService(service, conn, flags);
}
通过代码可以发现,绑定服务工作转换到mBase.bindService,mBase又是一个什么东西呢?点击查看
Context mBase;发现就是个上下文.context是一个抽象类,它的实现类是ContextImp
于是乎我们查看ContextImp类中的代码
  @Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        warnIfCallingFromSystemProcess();
        return bindServiceCommon(service, conn, flags, Process.myUserHandle());
    }
然后会调用bindServiceCommon方法
 private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
            UserHandle user) {
        IServiceConnection sd;
        if (conn == null) {
            throw new IllegalArgumentException("connection is null");
        }
        if (mPackageInfo != null) {
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
                    mMainThread.getHandler(), flags);
        } else {
            throw new RuntimeException("Not supported in system context");
        }
        validateServiceIntent(service);
        try {
            IBinder token = getActivityToken();
            if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
                    && mPackageInfo.getApplicationInfo().targetSdkVersion
                    < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                flags |= BIND_WAIVE_PRIORITY;
            }
            service.prepareToLeaveProcess();
            int res = ActivityManagerNative.getDefault().bindService(
                mMainThread.getApplicationThread(), getActivityToken(),
                service, service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, user.getIdentifier());
            if (res < 0) {
                throw new SecurityException(
                        "Not allowed to bind to service " + service);
            }
            return res != 0;
        } catch (RemoteException e) {
            return false;
        }
    }
通过代码可以发现内部会调用 validateServiceIntent(service);他是干什么的呢?

 private void validateServiceIntent(Intent service) {
        if (service.getComponent() == null && service.getPackage() == null) {
            if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
                IllegalArgumentException ex = new IllegalArgumentException(
                        "Service Intent must be explicit: " + service);
                throw ex;
            } else {
                Log.w(TAG, "Implicit intents with startService are not safe: " + service
                        + " " + Debug.getCallers(2, 3));
            }
        }
    }
通过代码可以发现在5.0以上的异常就是他抛出来的,他会通过传进去的intent进行判断包名(远程的包名)是否为空,并判断当前版本是否大于版本LOLLIPOP,
如果是5.0以上的则直接抛出一个异常,低于5.0的未做处理,这就是为什么在4.0能正常启动远程服务,5.0不可以的原因.在此贴上正确代码
 	intent.setAction("wsls.MyService");
        intent.setPackage("com.wsl.test");//这句不能少
        mConn = new MyServiceConnection();
        boolean b = bindService(intent, mConn, Context.BIND_AUTO_CREATE);

分析到此结束

另外补充一点,包名一定要以com开头,不然也无法启动远程的服务

初次写博客,请大家多多包涵,欢迎大家吐槽




<think>嗯,用户想找Mosquitto在Windows上的安装教程。我需要先整理一下现有的引用内容。引用3提到要选择合适的版本,比如mosquitto-2.0.15-install-windows-x64.exe,所以应该从官网下载。引用5提到了一些安装时的,比如绑定IP和匿名登录的设置,需要注意。安装步骤可能包括下载、运行安装程序、配置环境变量,然后验证安装。启动服务的话,引用1用了systemctl,但Windows下应该用net start或者服务管理器。另外,引用2说Mosquitto容易部署,但用户可能在配置时会遇到问题,比如匿名登录需要设置allow_anonymous true,还有桥接配置的问题,引用5也提到这些。所以安装指南里要包含这些注意事项,避免用户。可能的问题包括如何测试安装是否成功,如何处理端口占用,或者如何配置TLS。最后生成相关问题,帮助用户深入使用Mosquitto。</think>### Mosquitto Windows 安装指南 #### 1. **下载安装包** - 访问[官方下载页面](https://mosquitto.org/download/),选择适合Windows的版本。根据引用[3],推荐选择`mosquitto-2.0.15-install-windows-x64.exe`(具体版本号可能随更新变化)[^3]。 - 注意:需根据系统位数(32位或64位)选择对应安装包。 #### 2. **运行安装程序** - 双击下载的`.exe`文件,按向导完成安装。 - 默认安装路径为`C:\Program Files\mosquitto`,建议保持默认。 #### 3. **配置环境变量** - 将Mosquitto的安装路径(如`C:\Program Files\mosquitto`)添加到系统环境变量`PATH`中,以便命令行直接调用`mosquitto`命令。 #### 4. **验证安装** - 打开命令提示符(CMD),输入以下命令: ```bash mosquitto -v ``` - 若显示版本信息(如`mosquitto version 2.0.15`),则安装成功。 #### 5. **启动服务** - 通过命令启动Mosquitto服务: ```bash net start mosquitto ``` - 若需停止服务,使用`net stop mosquitto`[^1]。 #### 6. **配置匿名访问(可选)** - 编辑配置文件`mosquitto.conf`(位于安装目录的`etc`文件夹),添加: ```plaintext allow_anonymous true ``` - 此配置允许匿名连接,适合测试环境[^5]。 #### 注意事项 1. **绑定IP问题**:若需桥接或远程访问,需在配置文件中明确设置监听IP,如: ```plaintext listener 1883 0.0.0.0 ``` 2. **防火墙设置**:确保Windows防火墙开放MQTT默认端口(如1883)。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值