diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/service/MyMqttService.java b/moduleUtil/src/main/java/com/xscm/moduleutil/service/MyMqttService.java index d1cec84..e012dcd 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/service/MyMqttService.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/service/MyMqttService.java @@ -1,7 +1,6 @@ package com.xscm.moduleutil.service; - import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -15,6 +14,7 @@ import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; +import android.os.Looper; import android.util.Log; @@ -39,15 +39,16 @@ import org.jetbrains.annotations.Nullable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; -public class MyMqttService extends Service implements MyEmqttConnectListener,MyEmqttMesgListener,MyEmqttSubscribeListener{ +public class MyMqttService extends Service implements MyEmqttConnectListener, MyEmqttMesgListener, MyEmqttSubscribeListener { private final static String TAG = "lxj"; private static int qos = 2; -// private static String HOST ="tcp://81.70.45.221";//正式 - private static String HOST ="tcp://47.120.21.132";//测试 + // private static String HOST ="tcp://81.70.45.221";//正式 + private static String HOST = "tcp://47.120.21.132";//测试 private static MqttAndroidClient mqttAndroidClient; private MqttConnectOptions mMqttConnectOptions; private static boolean b = true; @@ -178,75 +179,91 @@ public class MyMqttService extends Service implements MyEmqttConnectListener,MyE * * @param message 消息 */ - public static void publish(String topic, String message) throws MqttException { + public static void publish(String topic, String message) { if (mqttAndroidClient == null) { Logger.e(TAG, "mqttAndroidClient is null", "发送失败"); return; } - //参数分别为:主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息 - IMqttDeliveryToken publish = mqttAndroidClient.publish(topic, message.getBytes(), qos, false); - publish.setActionCallback(new IMqttActionListener() { - @Override - public void onSuccess(IMqttToken asyncActionToken) { - Logger.e(TAG, "发送消息", "发送成功"); - } - @Override - public void onFailure(IMqttToken asyncActionToken, Throwable exception) { - Logger.e(TAG, "发送消息", "发送失败"); + // 在后台线程执行发布操作 + Handler handler = new Handler(Looper.getMainLooper()); + handler.post(() -> { + try { + //参数分别为:主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息 + IMqttDeliveryToken publish = mqttAndroidClient.publish(topic, message.getBytes(), qos, false); + publish.setActionCallback(new IMqttActionListener() { + @Override + public void onSuccess(IMqttToken asyncActionToken) { + Logger.e(TAG, "发送消息", "发送成功"); + } + + @Override + public void onFailure(IMqttToken asyncActionToken, Throwable exception) { + Logger.e(TAG, "发送消息", "发送失败: " + exception.getMessage()); + } + }); + } catch (Exception e) { + Logger.e(TAG, "发送消息", "发送异常: " + e.getMessage()); } }); } - public static void subscribe(String topic) { - try { - if (mqttAndroidClient.isConnected()) { - IMqttToken subToken = mqttAndroidClient.subscribe(topic, qos); - subToken.setActionCallback(new IMqttActionListener() { - @Override - public void onSuccess(IMqttToken asyncActionToken) { - if (mMyEmqttSubscribeListener != null) { - mMyEmqttSubscribeListener.onSubscribeSuccess(topic); + // 在后台线程执行订阅操作 + Handler handler = new Handler(Looper.getMainLooper()); + handler.post(() -> { + try { + if (mqttAndroidClient != null && mqttAndroidClient.isConnected()) { + IMqttToken subToken = mqttAndroidClient.subscribe(topic, qos); + subToken.setActionCallback(new IMqttActionListener() { + @Override + public void onSuccess(IMqttToken asyncActionToken) { + if (mMyEmqttSubscribeListener != null) { + mMyEmqttSubscribeListener.onSubscribeSuccess(topic); + } + Logger.e(TAG, "订阅成功:" + topic); } - Logger.e(TAG, "订阅成功:" + topic); - } - @Override - public void onFailure(IMqttToken asyncActionToken, - Throwable exception) { - if (!TOPIC_BOSS.equals(topic) && mMyEmqttSubscribeListener != null) { - mMyEmqttSubscribeListener.onSubscribeFailure(); + @Override + public void onFailure(IMqttToken asyncActionToken, + Throwable exception) { + if (!TOPIC_BOSS.equals(topic) && mMyEmqttSubscribeListener != null) { + mMyEmqttSubscribeListener.onSubscribeFailure(); + } + Logger.e(TAG, "订阅失败:" + topic + ", error: " + exception.getMessage()); } - Logger.e(TAG, "订阅失败:" + topic); - } - }); + }); + } + } catch (Exception e) { + Log.e(TAG, "订阅异常:" + topic, e); } - } catch (Exception e) { - e.printStackTrace(); - } + }); } public static void cleanSubscribe(String topic) { - try { - if (mqttAndroidClient.isConnected()) { - IMqttToken subToken = mqttAndroidClient.unsubscribe(topic); - subToken.setActionCallback(new IMqttActionListener() { - @Override - public void onSuccess(IMqttToken asyncActionToken) { - Logger.e(TAG, "取消成功" + topic); - } + // 在后台线程执行取消订阅操作 + Handler handler = new Handler(Looper.getMainLooper()); + handler.post(() -> { + try { + if (mqttAndroidClient != null && mqttAndroidClient.isConnected()) { + IMqttToken subToken = mqttAndroidClient.unsubscribe(topic); + subToken.setActionCallback(new IMqttActionListener() { + @Override + public void onSuccess(IMqttToken asyncActionToken) { + Logger.e(TAG, "取消成功" + topic); + } - @Override - public void onFailure(IMqttToken asyncActionToken, - Throwable exception) { - Logger.e(TAG, "取消失败" + topic); - } - }); + @Override + public void onFailure(IMqttToken asyncActionToken, + Throwable exception) { + Logger.e(TAG, "取消失败" + topic + ", error: " + exception.getMessage()); + } + }); + } + } catch (Exception e) { + Log.e(TAG, "取消订阅异常:" + topic, e); } - } catch (Exception e) { - e.printStackTrace(); - } + }); } @@ -265,67 +282,99 @@ public class MyMqttService extends Service implements MyEmqttConnectListener,MyE // mMqttConnectOptions.setPassword(new char[0]); //设置密码 mMqttConnectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1); - if (!mqttAndroidClient.isConnected()) { + if (mqttAndroidClient != null && !mqttAndroidClient.isConnected()) { doClientConnection(); } } private void doClientConnection() throws MqttException { - if (mqttAndroidClient != null && !mqttAndroidClient.isConnected() && isConnectIsNomarl() && b) { - mqttAndroidClient.connect(mMqttConnectOptions, null, iMqttActionListener); - } + // 在后台线程执行连接操作 + mqttHandler.post(() -> { + if (mqttAndroidClient != null && !mqttAndroidClient.isConnected() && isConnectIsNomarl() && b) { + try { + mqttAndroidClient.connect(mMqttConnectOptions, null, iMqttActionListener); + } catch (Exception e) { + Log.e(TAG, "MQTT连接异常", e); + handleConnectionFailure(); + } + } + }); } - public static void closeConnection() throws MqttException { - if (mqttAndroidClient.isConnected()) { - IMqttToken disconnect = mqttAndroidClient.disconnect(); - disconnect.setActionCallback(new IMqttActionListener() { - @Override - public void onSuccess(IMqttToken asyncActionToken) { - Logger.e(TAG, "断开链接", "断开链接成功"); - } - - @Override - public void onFailure(IMqttToken asyncActionToken, Throwable exception) { - Logger.e(TAG, "断开链接", "断开链接失败" + exception.getMessage()); - } - }); - } - } - - /** - * 判断网络是否连接 - */ - private boolean isConnectIsNomarl() { - ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo info = connectivityManager.getActiveNetworkInfo(); - if (info != null && info.isAvailable()) { - String name = info.getTypeName(); - Log.i(TAG, "当前网络名称:" + name); - return true; - } else { - Log.i(TAG, "没有可用网络"); - /*没有可用网络的时候,延迟3秒再尝试重连*/ - HandlerUtil.getInstance(this).postDelayed(new Runnable() { - @Override - public void run() { + private void handleConnectionFailure() { + retryCount++; + if (retryCount < MAX_RETRY_ATTEMPTS) { + // 延迟重试 + mqttHandler.postDelayed(() -> { + if (b) { try { doClientConnection(); } catch (MqttException e) { throw new RuntimeException(e); } } - }, 3000); - return false; + }, 5000); // 5秒后重试 + } else { + Log.w(TAG, "达到最大重试次数,停止重试"); + retryCount = 0; } } + public static void closeConnection() { + Handler handler = new Handler(Looper.getMainLooper()); + handler.post(() -> { + try { + if (mqttAndroidClient != null && mqttAndroidClient.isConnected()) { + IMqttToken disconnect = mqttAndroidClient.disconnect(); + disconnect.setActionCallback(new IMqttActionListener() { + @Override + public void onSuccess(IMqttToken asyncActionToken) { + Logger.e(TAG, "断开链接", "断开链接成功"); + } + + @Override + public void onFailure(IMqttToken asyncActionToken, Throwable exception) { + Logger.e(TAG, "断开链接", "断开链接失败" + exception.getMessage()); + } + }); + } + } catch (Exception e) { + Log.e(TAG, "关闭连接异常", e); + } + }); + } + + + /** + * 判断网络是否连接 + */ + private boolean isConnectIsNomarl() { + try { + ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); + if (connectivityManager != null) { + NetworkInfo info = connectivityManager.getActiveNetworkInfo(); + if (info != null && info.isAvailable()) { + String name = info.getTypeName(); + Log.i(TAG, "当前网络名称:" + name); + return true; + } else { + Log.i(TAG, "没有可用网络"); + return false; + } + } + } catch (Exception e) { + Log.e(TAG, "检查网络状态异常", e); + } + return false; + } + //MQTT是否连接成功的监听 private IMqttActionListener iMqttActionListener = new IMqttActionListener() { @Override public void onSuccess(IMqttToken arg0) { + retryCount = 0; // 重置重试计数 if (mMyEmqttConnectListener != null) { mMyEmqttConnectListener.onConnectSuccess(); } @@ -341,18 +390,12 @@ public class MyMqttService extends Service implements MyEmqttConnectListener,MyE // if (arg0 instanceof MqttException) { //// Logger.e(TAG, "链接状态:", "链接失败" + ((MqttException) arg1).getMessage()); // } - HandlerUtil.getInstance(getApplicationContext()).postDelayed(new Runnable() { - @Override - public void run() { - if (b) { - try { - doClientConnection(); - } catch (MqttException e) { - throw new RuntimeException(e); - } - } + // 在后台线程处理重连 + mqttHandler.postDelayed(() -> { + if (b) { + handleConnectionFailure(); } - }, 3000); + }, 1000); } }; @@ -362,15 +405,26 @@ public class MyMqttService extends Service implements MyEmqttConnectListener,MyE @Override public void messageArrived(String topic, MqttMessage message) throws Exception { - if (mMyEmqttMesgListener != null) { - mMyEmqttMesgListener.messageArrived(topic, message.toString()); - } - Logger.e(TAG, "收到的消息", "主题:" + topic + " 收到的消息:" + message.toString()); - //收到其他客户端的消息后,响应给对方告知消息已到达或者消息有问题等 - receiveMessage(topic,message.toString()); -// if (TOPIC_BOSS.equals(topic)) { -// EventBus.getDefault().post(new BossMsgEvent(message.toString())); -// } + // 将消息处理放到后台线程执行 + messageExecutorService.execute(() -> { + try { + String messageStr = message.toString(); + Logger.e(TAG, "收到的消息", "主题:" + topic + " 收到的消息:" + messageStr); + + // 处理消息 + receiveMessage(topic, messageStr); + + // 通知监听器 + if (mMyEmqttMesgListener != null) { + // 切换到主线程通知 + new Handler(Looper.getMainLooper()).post(() -> { + mMyEmqttMesgListener.messageArrived(topic, messageStr); + }); + } + } catch (Exception e) { + Log.e(TAG, "处理MQTT消息异常", e); + } + }); } @@ -384,35 +438,39 @@ public class MyMqttService extends Service implements MyEmqttConnectListener,MyE if (mMyEmqttConnectListener != null) { mMyEmqttConnectListener.onConnectFailure(); } - Logger.e(TAG, "链接状态:", "链接断开"); + Logger.e(TAG, "链接状态:", "链接断开: " + arg0.getMessage()); - HandlerUtil.getInstance(getApplicationContext()).postDelayed(new Runnable() { - @Override - public void run() { - if (b) { - try { - doClientConnection(); - } catch (MqttException e) { - throw new RuntimeException(e); - } + // 在后台线程处理重连 + mqttHandler.postDelayed(() -> { + if (b) { + try { + doClientConnection(); + } catch (MqttException e) { + throw new RuntimeException(e); } } - }, 300); + }, 1000); } }; private void receiveMessage(String topic, String data) { - JSONObject jsonObject = null; try { String newdata = data;//TextLengthUtil.decode(data); - jsonObject = JSON.parseObject(newdata); - } catch (Exception e) { - e.printStackTrace(); - return; - } + JSONObject jsonObject = JSON.parseObject(newdata); - int type = jsonObject.getIntValue("type"); - String message = jsonObject.getString("msg"); + int type = jsonObject.getIntValue("type"); + String message = jsonObject.getString("msg"); + + // 将事件处理放到主线程执行 + new Handler(Looper.getMainLooper()).post(() -> { + processMessageType(type, message); + }); + } catch (Exception e) { + Log.e(TAG, "解析MQTT消息异常", e); + } + } + + private void processMessageType(int type, String message) { switch (type) { case 3001://抢糖果游戏 break; @@ -437,9 +495,8 @@ public class MyMqttService extends Service implements MyEmqttConnectListener,MyE case 5016://推送房间-删除房间管理员 break; case 5017://用户开关麦 -// EventBus.getDefault().post(JSON.parseObject(message, WheatVoiceModel.class)); break; - case 5019://推送所有人-横幅礼物通知c + case 5019://推送所有人-横幅礼物通知 new RoomGiftRunable(message).run(); break; case 5020://推送房间-聊天室礼物通知 @@ -521,7 +578,6 @@ public class MyMqttService extends Service implements MyEmqttConnectListener,MyE break; case 5062://交友房换麦 Logger.e("环信5062", message); -// sendEventList(message, RoomPitBean.class); break; case 5063://进入小黑屋 Logger.e("环信5063", message); @@ -560,20 +616,40 @@ public class MyMqttService extends Service implements MyEmqttConnectListener,MyE break; } } + @Override public void onDestroy() { + b = false; + try { + // 清理资源 + if (messageExecutorService != null) { + messageExecutorService.shutdown(); + try { + if (!messageExecutorService.awaitTermination(5, TimeUnit.SECONDS)) { + messageExecutorService.shutdownNow(); + } + } catch (InterruptedException e) { + messageExecutorService.shutdownNow(); + } + } + + if (mqttHandlerThread != null) { + mqttHandlerThread.quitSafely(); + } + cleanSubscribe(TOPIC_BOSS); if (mqttAndroidClient != null) { mqttAndroidClient.disconnect(); //断开连接 mqttAndroidClient.unregisterResources(); mqttAndroidClient = null; - stopForeground(true); // 停止前台服务 } + stopForeground(true); // 停止前台服务 Logger.e(TAG, "服务关闭", "资源释放成功"); } catch (Exception e) { - e.printStackTrace(); + Log.e(TAG, "服务关闭异常", e); } + super.onDestroy(); } @@ -615,7 +691,4 @@ public class MyMqttService extends Service implements MyEmqttConnectListener,MyE public void onSubscribeFailure() { } -} - - - +} \ No newline at end of file diff --git a/moduleroom/src/main/java/com/example/moduleroom/activity/RoomActivity.java b/moduleroom/src/main/java/com/example/moduleroom/activity/RoomActivity.java index 12ccf5a..b93a6f8 100644 --- a/moduleroom/src/main/java/com/example/moduleroom/activity/RoomActivity.java +++ b/moduleroom/src/main/java/com/example/moduleroom/activity/RoomActivity.java @@ -20,6 +20,7 @@ import android.os.CountDownTimer; import android.os.Looper; import android.text.SpannableStringBuilder; import android.text.TextUtils; +import android.util.DisplayMetrics; import android.util.Log; import android.view.GestureDetector; import android.view.Gravity; @@ -40,6 +41,7 @@ import android.widget.RelativeLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.constraintlayout.widget.ConstraintLayout; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; @@ -186,7 +188,8 @@ public class RoomActivity extends BaseMvpActivity 0) { + // 设置 vp_room_pager 占用 70% 空间 + ConstraintLayout.LayoutParams pagerParams = (ConstraintLayout.LayoutParams) pager.getLayoutParams(); + pagerParams.height = 0; + pager.setLayoutParams(pagerParams); + + // 设置 ease_container 占用 30% 空间 + ConstraintLayout.LayoutParams easeParams = (ConstraintLayout.LayoutParams) easeContainer.getLayoutParams(); + easeParams.height = 0; + easeContainer.setLayoutParams(easeParams); + + // 请求重新布局 + mainContainer.requestLayout(); + } + } + } catch (Exception e) { + LogUtils.e("adjustLayoutHeights error: " + e.getMessage()); + } + } + + /** + * 获取状态栏高度 + */ + private int getStatusBarHeight() { + int result = 0; + int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (resourceId > 0) { + result = getResources().getDimensionPixelSize(resourceId); + } + return result; + } + + @Override public void getRoomOnline(RoomOnline onlineBean) { if (onlineBean != null) { diff --git a/moduleroom/src/main/java/com/example/moduleroom/adapter/EaseChatAdapter.java b/moduleroom/src/main/java/com/example/moduleroom/adapter/EaseChatAdapter.java index ec02c8a..ce4695e 100644 --- a/moduleroom/src/main/java/com/example/moduleroom/adapter/EaseChatAdapter.java +++ b/moduleroom/src/main/java/com/example/moduleroom/adapter/EaseChatAdapter.java @@ -456,17 +456,21 @@ public class EaseChatAdapter extends BaseMultiItemQuickAdapter - - - - - - - - - - - - - - - - - - - - - - /> + - - - - + android:layout_height="0dp" + android:layout_marginBottom="@dimen/dp_5" + android:clipChildren="false" + android:clipToPadding="false" + app:layout_constraintBottom_toTopOf="@+id/guideline_horizontal" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:layout_marginEnd="@dimen/dp_16" + android:visibility="gone"/>