From 5635d0c707b8a1d24d9335820752490b08b3f776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E5=B0=8F=E6=B1=9F?= <461355754@qq.com> Date: Sat, 13 Sep 2025 15:36:44 +0800 Subject: [PATCH] =?UTF-8?q?1=EF=BC=9A=E4=BF=AE=E6=94=B9=E6=92=AD=E6=94=BE?= =?UTF-8?q?=E7=A4=BC=E7=89=A9=E7=89=B9=E6=95=88=202=EF=BC=9A=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E7=89=B9=E6=95=88=E6=8C=89=E7=85=A7ios=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 +- gradle.properties | 2 +- .../moduleutil/widget/AvatarFrameView.java | 174 +++++++++---- .../xscm/moduleutil/widget/BaseWheatView.java | 2 +- .../moduleutil/widget/WheatLayoutManager.java | 10 + .../widget/WheatLayoutSingManager.java | 18 ++ .../res/layout/room_view_friendship_wheat.xml | 3 +- .../modulemain/presenter/HomePresenter.java | 3 + .../moduleroom/activity/RoomActivity.java | 239 +++++++++++------- .../fragment/RoomAuctionFragment.java | 4 +- .../moduleroom/fragment/RoomFragment.java | 6 +- .../moduleroom/fragment/RoomKtvFragment.java | 7 +- .../moduleroom/fragment/SingSongFragment.java | 6 +- .../src/main/res/layout/activity_room.xml | 27 +- .../main/res/layout/fragment_room_auction.xml | 16 +- .../src/main/res/layout/fragment_room_ktv.xml | 2 +- moduleroom/src/main/res/layout/room_top.xml | 8 +- .../zhuangb/ZhuangBanShangChengAdapter.java | 2 +- 18 files changed, 344 insertions(+), 189 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a80d20a..84844cd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -55,7 +55,7 @@ android { } buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release @@ -77,7 +77,7 @@ android { debug { debuggable true - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.debug diff --git a/gradle.properties b/gradle.properties index 8f6a48a..0b08931 100644 --- a/gradle.properties +++ b/gradle.properties @@ -30,7 +30,7 @@ isBuildModule=false android.injected.testOnly=false APP_VERSION_NAME=1.0.0 -APP_VERSION_CODE=121 +APP_VERSION_CODE=125 org.gradle.jvm.toolchain.useLegacyAdapters=false #org.gradle.java.home=C\:\\Users\\qx\\.jdks\\ms-17.0.15 diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AvatarFrameView.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AvatarFrameView.java index e95d8c9..2c7fe97 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AvatarFrameView.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/AvatarFrameView.java @@ -44,6 +44,8 @@ import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.Map; import java.util.Queue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; import okhttp3.Call; import okhttp3.Callback; @@ -121,7 +123,7 @@ public class AvatarFrameView extends FrameLayout { private ChannelSplitRenderer1 renderer; private int mType;//1:循环播放 2:播放一次停止播放 private File mFile; - private final Queue playQueue = new LinkedList<>(); + private final BlockingQueue playQueue = new LinkedBlockingQueue<>(); private boolean isPlaying = false; // 添加销毁标记 @@ -224,7 +226,7 @@ public class AvatarFrameView extends FrameLayout { return ""; } - private void playNextFromQueue() { + public void playNextFromQueue() { // if (isDestroyed) return; // 确保在主线程中执行 // if (Looper.myLooper() != Looper.getMainLooper()) { @@ -238,33 +240,39 @@ public class AvatarFrameView extends FrameLayout { return; } // 检查是否可以开始新的播放 - if (!playbackManager.canStartNewPlayback()) { - Logger.d("AvatarFrameView", "Max concurrent playbacks reached, waiting..."); - return; - } +// if (!playbackManager.canStartNewPlayback()) { +// Logger.d("AvatarFrameView", "Max concurrent playbacks reached, waiting..."); +// return; +// } - PlayItem item = playQueue.poll(); - if (item != null) { - // 通知开始播放 - playbackManager.onStartPlayback(); - isPlaying = true; + if (!isPlaying || !isActuallyPlaying()) { - // 处理播放项目 - processPlayItem(item); - } else { - isPlaying = false; - Logger.d("AvatarFrameView", "Queue is empty, stop playing"); + PlayItem item = playQueue.poll(); + if (item != null) { + // 通知开始播放 + playbackManager.onStartPlayback(); + isPlaying = true; + + // 处理播放项目 + processPlayItem(item); + + } else { + isPlaying = false; + Logger.d("AvatarFrameView", "Queue is empty, stop playing"); + } } } // 添加统一的播放完成处理方法 public void onPlaybackComplete() { + if (isDestroyed) return; mainHandler.post(() -> { + // 再次检查是否已销毁 if (isDestroyed) return; - // 通知播放管理器播放完成 - playbackManager.onFinishPlayback(); +// // 通知播放管理器播放完成 +// playbackManager.onFinishPlayback(); // 重置播放状态 isPlaying = false; @@ -280,19 +288,25 @@ public class AvatarFrameView extends FrameLayout { private void processPlayItem(PlayItem item) { try { - clearPrevious(); +// clearPrevious(); String ext = getFileExtension(item.url); if ("svga".equalsIgnoreCase(ext)) { - renderType = RenderType.SVGA; - mType = item.type; - mBinding.playView.setVisibility(View.GONE); - loadSVGA(item.url); + mainHandler.post(() -> { + renderType = RenderType.SVGA; + mType = item.type; + if (mBinding != null) { + mBinding.playView.setVisibility(View.GONE); + } + loadSVGA(item.url); + } ); } else if ("mp4".equalsIgnoreCase(ext)) { - renderType = RenderType.MP4; - mType = item.type; - mBinding.playView.setVisibility(View.VISIBLE); - downloadAndPlayMp4(item.url); + mainHandler.post(() -> { + renderType = RenderType.MP4; + mType = item.type; + mBinding.playView.setVisibility(View.VISIBLE); + downloadAndPlayMp4(item.url); + } ); } else { // 不支持的格式,直接完成 handlePlaybackComplete(); @@ -314,8 +328,11 @@ public class AvatarFrameView extends FrameLayout { return false; } - public boolean isPlaying(){ - return mBinding.playView.isRunning(); + public boolean isPlaying() { + if (mBinding!=null && mBinding.playView!=null) { + return mBinding.playView.isRunning(); + } + return true; } // 在 AvatarFrameView 类中添加以下代码 @@ -330,24 +347,12 @@ public class AvatarFrameView extends FrameLayout { mainHandler.post(() -> setSource(url, type2)); return; } -// // 检查内存状态 -// if (isMemoryLow()) { -// LogUtils.w(TAG, "Low memory, skipping animation"); -// clearQueue(); -// return; -// } - // 检查特效是否开启 -// if (SpUtil.getOpenEffect() != 1) { -// // 特效关闭时清空队列并停止播放 -// clearQueue(); -// return; -// } // 添加到播放队列 playQueue.add(new PlayItem(url, type2)); Logger.d("AvatarFrameView", "Added to queue, queue size: " + playQueue.size() + ", url: " + url); - if (type2 == 3) { + if (type2 == 3 || type2 == 1) { // playNextFromQueue(); loadSVGA(url); } else { @@ -461,12 +466,22 @@ public class AvatarFrameView extends FrameLayout { @Override public void onFailure(Call call, IOException e) { LogUtils.e("MP4下载失败: " + e.toString()); - onPlaybackComplete(); + mainHandler.post(() -> { + // 检查是否已销毁 + if (!isDestroyed) { + onPlaybackComplete(); + } + }); } // 更简单的优化版本 @Override public void onResponse(Call call, Response response) throws IOException { + // 在异步回调中首先检查是否已销毁 + if (isDestroyed) { + LogUtils.w(TAG, "View destroyed before download completed"); + return; + } LogUtils.d("@@@@", "onResponse" + Thread.currentThread().getName()); if (response.isSuccessful()) { try (ResponseBody responseBody = response.body()) { @@ -493,31 +508,62 @@ public class AvatarFrameView extends FrameLayout { fos.flush(); isTxk = true; mainHandler.post(() -> { - LogUtils.d("@@@@Thread", Thread.currentThread().getName()); - playMp4File(file); + // 关键:在执行UI操作前再次检查是否已销毁 + if (downloadedFile.exists()) { + LogUtils.d("@@@@Thread", Thread.currentThread().getName()); + playMp4File(downloadedFile); // 使用正确的文件引用 + } else { + LogUtils.w(TAG, "View destroyed or file not exist after download"); + onPlaybackComplete(); + } }); } catch (IOException e) { LogUtils.e("MP4文件保存失败: " + e.getMessage()); + mainHandler.post(() -> { + if (!isDestroyed) { + onPlaybackComplete(); + } + }); } } else { - mainHandler.post(() -> onPlaybackComplete()); + mainHandler.post(() -> { + if (!isDestroyed) { + onPlaybackComplete(); + } + }); } } catch (Exception e) { LogUtils.e("MP4文件保存失败: " + e.getMessage()); - mainHandler.post(() -> onPlaybackComplete()); + mainHandler.post(() -> { + if (!isDestroyed) { + onPlaybackComplete(); + } + }); } } else { LogUtils.e("MP4下载响应失败"); - mainHandler.post(() -> onPlaybackComplete()); + mainHandler.post(() -> { + if (!isDestroyed) { + onPlaybackComplete(); + } + }); } } }); } else { isTxk = true; LogUtils.e("有缓存"); - playMp4File(file); + mainHandler.post(() -> { + // 检查是否已销毁 + if ( file.exists()) { + playMp4File(file); + } else { + LogUtils.w(TAG, "有缓存2222222222222"); +// onPlaybackComplete(); + } + }); // 直接播放缓存文件 // if (isTxk) { // mBinding.playView.setLoop(1); @@ -528,8 +574,20 @@ public class AvatarFrameView extends FrameLayout { private void playMp4File(File file) { try { - if (mBinding != null && file != null && file.exists()) { -// mBinding.playView.setAnimListener(new MP4PlaybackCallback()); + // 双重检查确保组件未被销毁 + if (isDestroyed) { + LogUtils.w(TAG, "Attempt to play MP4 file after view destroyed"); + onPlaybackComplete(); + return; + } + + if (mBinding == null || mBinding.playView == null) { + LogUtils.w(TAG, "PlayView is null"); + onPlaybackComplete(); + return; + } + + if (file != null && file.exists()) { // 设置循环次数(根据mType决定) if (mType == 1) { mBinding.playView.setLoop(0); // 无限循环 @@ -537,9 +595,15 @@ public class AvatarFrameView extends FrameLayout { mBinding.playView.setLoop(1); // 播放一次 } - // 开始播放 - mBinding.playView.startPlay(file); + // 开始播放前检查视图状态 + if (!isDestroyed && mBinding != null && mBinding.playView != null) { + mBinding.playView.startPlay(file); + } else { + LogUtils.w(TAG, "View was destroyed before MP4 playback started"); + onPlaybackComplete(); + } } else { + LogUtils.e("播放MP4文件出错: 文件不存在或已损坏"); onPlaybackComplete(); } } catch (Exception e) { @@ -1265,7 +1329,7 @@ public class AvatarFrameView extends FrameLayout { } try { - clearPrevious(); // 清除之前的动画 +// clearPrevious(); // 清除之前的动画 svgaSurface.setVisibility(View.VISIBLE); new SVGAParser(getContext()).decodeFromAssets(assetName, new SVGAParser.ParseCompletion() { @Override @@ -1363,7 +1427,7 @@ public class AvatarFrameView extends FrameLayout { // 内存检查 if (playQueue.size() % 5 == 0) { - performLightMemoryCleanup(); +// performLightMemoryCleanup(); } // 播放下一个 diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java index 51f55d9..c75244e 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java @@ -160,7 +160,7 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe setCardiac(pitBean.getCharm(), getTzbl()); setPitData(bean); - if (bean.getIs_online() == 2){ + if (bean.getIs_online() == 2 && bean.getUser_id()!=null && !bean.getUser_id().equals("0") && !bean.getUser_id().isEmpty()){ iv_on_line.setVisibility(VISIBLE); }else { iv_on_line.setVisibility(GONE); diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutManager.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutManager.java index 261b6bc..2efcbd7 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutManager.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutManager.java @@ -238,6 +238,16 @@ public class WheatLayoutManager { } } + public void updateSingleCharm(RoomPitBean pitBean, int pitNumber) { + if (pitList == null || pitList.isEmpty() || pitNumber < 1 || pitNumber > 10) return; + if (isSingleMode && this.currentSinglePit != pitNumber) return; + + RoomDefaultWheatView wheatView = findWheatViewByPitNumber(pitNumber); + if (wheatView != null) { + wheatView.setCharm(pitBean.getCharm()); + } + } + @Nullable private RoomDefaultWheatView findWheatViewByPitNumber(int pitNumber) { for (int i = 0; i < container.getChildCount(); i++) { diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java index 1fa87d1..abb2804 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java @@ -402,6 +402,24 @@ public class WheatLayoutSingManager { } } + public void upDataCharm(RoomPitBean pitBean, int pitNumber){ + // 检查容器状态 + if (container == null || !isContainerValid()) { + return; + } + + if (pitList == null || pitList.isEmpty() || pitNumber < 1 || pitNumber > 10) return; + + // 如果是单个展示模式且不是当前麦位,不处理 + if (isSingleMode && this.currentSinglePit != pitNumber) return; + + RoomSingSongWheatView wheatView = findWheatViewByPitNumber(pitNumber); + if (wheatView != null) { + RoomPitBean bean = pitBean; + wheatView.setCharm(bean.getCharm()); // 刷新数据 + } + } + @Nullable private RoomSingSongWheatView findWheatViewByPitNumber(int pitNumber) { // 检查容器状态 diff --git a/moduleUtil/src/main/res/layout/room_view_friendship_wheat.xml b/moduleUtil/src/main/res/layout/room_view_friendship_wheat.xml index 049deca..1145cd6 100644 --- a/moduleUtil/src/main/res/layout/room_view_friendship_wheat.xml +++ b/moduleUtil/src/main/res/layout/room_view_friendship_wheat.xml @@ -35,8 +35,7 @@ android:scaleType="fitCenter" android:visibility="gone" tools:visibility="visible" - app:layout_constraintHeight_percent="1" - app:layout_constraintWidth_percent="1.05" + app:layout_constraintDimensionRatio="1:1" app:layout_constraintBottom_toBottomOf="@id/riv" app:layout_constraintEnd_toEndOf="@id/riv" app:layout_constraintStart_toStartOf="@id/riv" diff --git a/modulemain/src/main/java/com/xscm/modulemain/presenter/HomePresenter.java b/modulemain/src/main/java/com/xscm/modulemain/presenter/HomePresenter.java index 6d6a15f..9df7e01 100644 --- a/modulemain/src/main/java/com/xscm/modulemain/presenter/HomePresenter.java +++ b/modulemain/src/main/java/com/xscm/modulemain/presenter/HomePresenter.java @@ -370,6 +370,9 @@ public class HomePresenter extends BasePresenter implements H @Override public void onNext(ThemeBean themeBean) { + if (MvpRef==null){ + MvpRef = new WeakReference<>(mView); + } MvpRef.get().getThemeData(themeBean); } }); 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 286c67c..506f69d 100644 --- a/moduleroom/src/main/java/com/example/moduleroom/activity/RoomActivity.java +++ b/moduleroom/src/main/java/com/example/moduleroom/activity/RoomActivity.java @@ -139,6 +139,8 @@ import com.xscm.moduleutil.utils.SystemUtils; import com.xscm.moduleutil.widget.AvatarFrameView; import com.xscm.moduleutil.widget.CircularProgressView; import com.xscm.moduleutil.widget.CustomMusicFloatingView; +import com.xscm.moduleutil.widget.GiftAnimView; +import com.xscm.moduleutil.widget.QXGiftPlayerManager; import com.xscm.moduleutil.widget.SilentCountDownTimer; import com.xscm.moduleutil.widget.ViewUtils; import com.xscm.moduleutil.widget.floatingView.Floa; @@ -158,6 +160,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Queue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -301,6 +305,61 @@ public class RoomActivity extends BaseMvpActivity roomMessageEventQueue = new LinkedBlockingQueue<>(); + int i = 0; @Subscribe(threadMode = ThreadMode.MAIN) public void roomInfoEvent(RoomMessageEvent messageEvent) { if (messageEvent == null) return; + int msgType = messageEvent.getMsgType(); RoomMessageEvent.T text = messageEvent.getText(); if (msgType == 1005) { - handleMsgType1005(messageEvent, text); + LogUtils.e("@@@@" + "EventBusnujm2"+"playQueue.size()===="+ messageEvent.getText().getGiftInfo()); +// synchronized (roomMessageLock) { +// roomMessageEventQueue.add(messageEvent.getText().getGiftInfo().getPlay_image()); +// } + QXGiftPlayerManager.getInstance(this).displayFullEffectView(messageEvent.getText().getGiftInfo()); +// handleMsgType1005(messageEvent, text); + hand1005(messageEvent, text); } else if (msgType == 123) { EventBus.getDefault().post(new RoomSettingEvent()); } else if (msgType == 1014) { @@ -1106,7 +1161,7 @@ public class RoomActivity extends BaseMvpActivity playQueue = new LinkedList<>(); + private static volatile MP4PlaybackCallback sInstance; public static class MP4PlaybackCallback implements IAnimListener { @@ -1127,6 +1182,7 @@ public class RoomActivity extends BaseMvpActivity pitList = mRoomInfoResp.getRoom_info().getPit_list(); if (pitList == null) return; @@ -1211,35 +1266,22 @@ public class RoomActivity extends BaseMvpActivity 0 && roomId != null) { // MvpPre.userOnlineStatus(userIds.toString(), roomId); @@ -2653,6 +2690,8 @@ public class RoomActivity extends BaseMvpActivity--> - + + + + + + + + - + + + + + + + + - + + + + + + + + diff --git a/moduleroom/src/main/res/layout/fragment_room_ktv.xml b/moduleroom/src/main/res/layout/fragment_room_ktv.xml index 857c73d..29a7b84 100644 --- a/moduleroom/src/main/res/layout/fragment_room_ktv.xml +++ b/moduleroom/src/main/res/layout/fragment_room_ktv.xml @@ -317,7 +317,7 @@ android:layout_marginTop="-55dp" android:layout_marginEnd="@dimen/dp_5" android:clickable="true" - android:elevation="10dp" + android:elevation="9999dp" android:focusable="true" android:foreground="?android:attr/selectableItemBackground" android:translationZ="30dp" diff --git a/moduleroom/src/main/res/layout/room_top.xml b/moduleroom/src/main/res/layout/room_top.xml index 91568b2..7c981f7 100644 --- a/moduleroom/src/main/res/layout/room_top.xml +++ b/moduleroom/src/main/res/layout/room_top.xml @@ -198,7 +198,8 @@ android:layout_marginStart="@dimen/dp_12" android:background="@drawable/bg_r73_33fffff" android:layout_toEndOf="@id/btn_notice" - android:visibility="gone"> + android:visibility="gone" + tools:visibility="visible"> + + \ No newline at end of file diff --git a/modulevocal/src/main/java/com/example/modulevocal/fragment/zhuangb/ZhuangBanShangChengAdapter.java b/modulevocal/src/main/java/com/example/modulevocal/fragment/zhuangb/ZhuangBanShangChengAdapter.java index 8c037e4..dff834c 100644 --- a/modulevocal/src/main/java/com/example/modulevocal/fragment/zhuangb/ZhuangBanShangChengAdapter.java +++ b/modulevocal/src/main/java/com/example/modulevocal/fragment/zhuangb/ZhuangBanShangChengAdapter.java @@ -33,7 +33,7 @@ public class ZhuangBanShangChengAdapter extends BaseQuickAdapter