Android 12集成paho MQTT 3.3.0报MqttException未抛出编译错误
问题现象
在Android 12平台实现MQTT通信能力,按项目指引导入hannesa2/paho.mqtt.android 3.3.0版本AAR依赖完成全部配置后,编译阶段抛出错误:exception MqttException is never thrown in body of corresponding try statement,报错行号为109、123、174,均为代码中捕获MqttException的catch语句块。此前使用原版Paho MQTT库时无该编译问题,但旧版库最高仅兼容Android 11,无法在Android 12设备上正常运行。
问题根因
hannesa2/paho.mqtt.android 3.x版本对原版Paho库的API做了调整:connect()、publish()、disconnect()等核心操作方法不再同步抛出受检异常MqttException,所有操作异常全部通过IMqttActionListener的onFailure回调返回。Java语法不允许捕获对应try块中永远不会抛出的受检异常,因此直接沿用旧版库的try-catch写法会触发编译报错。
除此之外,原有业务代码缺失部分MQTT核心类的导入,即使解决异常捕获问题也无法正常编译。
修复步骤
- 移除所有无效的
MqttException捕获块
对应三处报错位置:connectToBroker()方法:删除包裹client.connect()的try-catch结构中捕获MqttException的分支,连接失败逻辑统一放到连接动作的onFailure回调中处理sendMessage()方法:将catch块的多异常捕获拆分为仅捕获UnsupportedEncodingException,移除MqttException的捕获逻辑,消息发送结果通过给publish()方法传入动作回调处理onDestroy()方法:删除包裹client.disconnect()的try-catch结构中捕获MqttException的分支,断连失败逻辑统一放到断连动作的onFailure回调中处理
- 补全缺失的类导入
在文件头部导入区补充以下类的引用:import info.mqtt.android.service.MqttClient; import info.mqtt.android.service.MqttMessage; import info.mqtt.android.service.MqttCallback; import info.mqtt.android.service.IMqttToken; import info.mqtt.android.service.IMqttActionListener; - 增加空判断避免运行时崩溃
对client对象增加非空校验,避免页面销毁时client未初始化就调用disconnect()触发空指针。
修复后核心代码参考
// connectToBroker方法修复后 void connectToBroker() { String clientId = MqttClient.generateClientId(); client = new MqttAndroidClient(this.getApplicationContext(), serverURL, clientId, Ack.AUTO_ACK); IMqttToken token = client.connect(); token.setActionCallback(new IMqttActionListener() { @SuppressLint("SetTextI18n") @Override public void onSuccess(IMqttToken asyncActionToken) { connectionStatus.setText("Connected To " + serverURL); connectionFlag = true; sendButton.setEnabled(true); subscribeButton.setEnabled(true); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { Toast.makeText(getApplicationContext(), "连接失败", Toast.LENGTH_SHORT).show(); } }); } // sendMessage方法修复后 void sendMessage(String topic) { String payload = textToSend.getText().toString(); byte[] encodedPayload; try { encodedPayload = payload.getBytes("UTF-8"); MqttMessage message = new MqttMessage(encodedPayload); client.publish(topic, message, null, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { Toast.makeText(getApplicationContext(), "发送成功", Toast.LENGTH_SHORT).show(); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { Toast.makeText(getApplicationContext(), "发送失败", Toast.LENGTH_SHORT).show(); } }); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } // onDestroy方法修复后 @Override protected void onDestroy() { super.onDestroy(); if (connectionFlag && client != null) { IMqttToken disconnectToken = client.disconnect(); disconnectToken.setActionCallback(new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { Toast.makeText(getApplicationContext(), "已断开连接", Toast.LENGTH_SHORT).show(); finish(); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { finish(); } }); connectionFlag = false; } }
注:
subscribeToTopic方法中捕获的是通用Exception,不会触发该编译错误,可根据业务需要自行调整为回调式异常处理。
内容的提问来源于stack exchange,提问作者Yaroslav Dmytriiev
相关产品推荐
相关产品推荐

