优化麦圈,泄漏处理
This commit is contained in:
@@ -256,13 +256,14 @@ public abstract class BaseAppCompatActivity<VDB extends ViewDataBinding> extends
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
EventBus.getDefault().unregister(this);
|
||||
|
||||
super.finish();
|
||||
LogUtils.e(this.getComponentName()+"========finish");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
EventBus.getDefault().unregister(this);
|
||||
// 移除背景更新监听器
|
||||
BackgroundManager.getInstance().removeListener(this);
|
||||
// 移除颜色变化监听器
|
||||
|
||||
@@ -18,6 +18,7 @@ import android.content.Context;
|
||||
import android.media.projection.MediaProjection;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.SystemClock;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
@@ -54,7 +55,9 @@ import java.io.FileInputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
@@ -120,6 +123,14 @@ public class AgoraManager {
|
||||
private Disposable disposableB;
|
||||
private Disposable disposableC;
|
||||
|
||||
// UI 刷新最小间隔(ms)
|
||||
private static final long SOUND_UI_INTERVAL = 200;
|
||||
|
||||
private final Handler uiHandler = new Handler(Looper.getMainLooper());
|
||||
private long lastDispatchTime = 0;
|
||||
|
||||
// 缓存本次声网回调的音量结果
|
||||
private final Map<String, Integer> volumeCache = new HashMap<>();
|
||||
public void setLastRoomId(String value) {
|
||||
lastRoomId = value;
|
||||
}
|
||||
@@ -549,22 +560,33 @@ public class AgoraManager {
|
||||
|
||||
if (speakers == null || speakers.length == 0) return;
|
||||
|
||||
for (final AudioVolumeInfo info : speakers) {
|
||||
final int uid = info.uid;
|
||||
final int volume = info.volume;
|
||||
// 1️⃣ 构建局部 Map(声网线程私有)
|
||||
Map<String, Integer> localMap = new HashMap<>();
|
||||
for (AudioVolumeInfo info : speakers) {
|
||||
String userId = info.uid > 0
|
||||
? String.valueOf(info.uid)
|
||||
: String.valueOf(SpUtil.getUserId());
|
||||
localMap.put(userId, info.volume);
|
||||
}
|
||||
|
||||
// 回调所有监听器
|
||||
long now = SystemClock.uptimeMillis();
|
||||
if (now - lastDispatchTime < SOUND_UI_INTERVAL) return;
|
||||
lastDispatchTime = now;
|
||||
|
||||
// 2️⃣ 只把“不可变快照”丢给 UI
|
||||
uiHandler.post(() -> dispatchVolume(localMap));
|
||||
}
|
||||
private void dispatchVolume(Map<String, Integer> volumeSnapshot) {
|
||||
if (soundLevelUpdateListeners.isEmpty()) return;
|
||||
|
||||
for (Map.Entry<String, Integer> entry : volumeSnapshot.entrySet()) {
|
||||
for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) {
|
||||
if (listener != null) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
// 远程用户音量变化
|
||||
listener.onRemoteSoundLevelUpdate(uid > 0 ? String.valueOf(uid) : SpUtil.getUserId() + "", volume);
|
||||
});
|
||||
listener.onRemoteSoundLevelUpdate(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocalVideoStateChanged(Constants.VideoSourceType source, int state, int reason) {
|
||||
super.onLocalVideoStateChanged(source, state, reason);
|
||||
|
||||
@@ -262,99 +262,16 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
|
||||
AgoraManager.getInstance().addSoundLevelListener(new SoundLevelUpdateListener() {
|
||||
@Override
|
||||
public void onRemoteSoundLevelUpdate(String userId, int soundLevel) {
|
||||
if (mIvRipple == null)
|
||||
return;
|
||||
if (mIvRipple == null) return;
|
||||
if (!userId.equals(pitBean.getUser_id())) return;
|
||||
|
||||
if (userId.equals(pitBean.getUser_id())) {
|
||||
if (soundLevel == 0) {
|
||||
mIvRipple.pauseAnimation();
|
||||
CommonAppContext.getInstance().onlineMap.put(pitBean.getUser_id(), 1);
|
||||
mIvRipple.setVisibility(INVISIBLE);
|
||||
} else {
|
||||
mIvRipple.setVisibility(VISIBLE);
|
||||
mIvRipple.post(() -> {
|
||||
if (!mIvRipple.isAnimating()) {
|
||||
if (pitBean.getMic_cycle() != null && !pitBean.getMic_cycle().isEmpty()) {
|
||||
if (mParser != null) {
|
||||
mIvRipple.startAnimation();
|
||||
} else {
|
||||
mParser = new SVGAParser(getContext());
|
||||
try {
|
||||
mParser.decodeFromURL(new URL(pitBean.getMic_cycle()), new SVGAParser.ParseCompletion() {
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(@NotNull SVGAVideoEntity svgaVideoEntity) {
|
||||
if (mIvRipple == null)
|
||||
return;
|
||||
SVGADrawable drawable = new SVGADrawable(svgaVideoEntity);
|
||||
mIvRipple.setImageDrawable(drawable);
|
||||
mIvRipple.startAnimation();
|
||||
}
|
||||
});
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
mIvRipple.startAnimation();
|
||||
}
|
||||
CommonAppContext.getInstance().onlineMap.put(pitBean.getUser_id(), 1);
|
||||
iv_on_line.setVisibility(GONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
boolean nowSpeaking = soundLevel > 0;
|
||||
updateSpeakingState(nowSpeaking);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocalSoundLevelUpdate(int volume) {
|
||||
if (mIvRipple == null)
|
||||
return;
|
||||
if (volume == 0) {
|
||||
mIvRipple.setVisibility(GONE);
|
||||
} else {
|
||||
mIvRipple.setVisibility(VISIBLE);
|
||||
if (!mIvRipple.isAnimating()) {
|
||||
if (pitBean.getMic_cycle()!=null && !pitBean.getMic_cycle().isEmpty()) {
|
||||
if (mParser != null) {
|
||||
mIvRipple.startAnimation();
|
||||
} else {
|
||||
mParser = new SVGAParser(getContext());
|
||||
try {
|
||||
mParser.decodeFromURL(new URL(pitBean.getMic_cycle()), new SVGAParser.ParseCompletion() {
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(@NotNull SVGAVideoEntity svgaVideoEntity) {
|
||||
if (mIvRipple == null)
|
||||
return;
|
||||
SVGADrawable drawable = new SVGADrawable(svgaVideoEntity);
|
||||
mIvRipple.setImageDrawable(drawable);
|
||||
mIvRipple.startAnimation();
|
||||
}
|
||||
});
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
|
||||
mIvRipple.startAnimation();
|
||||
}
|
||||
CommonAppContext.getInstance().onlineMap.put(pitBean.getUser_id(), 1);
|
||||
iv_on_line.setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -379,6 +296,59 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe
|
||||
|
||||
}
|
||||
|
||||
private boolean isSpeaking = false;
|
||||
|
||||
|
||||
private void updateSpeakingState(boolean nowSpeaking) {
|
||||
// 1️⃣ 状态未变化,直接丢弃(核心)
|
||||
if (nowSpeaking == isSpeaking) return;
|
||||
isSpeaking = nowSpeaking;
|
||||
|
||||
if (!nowSpeaking) {
|
||||
// 静音状态
|
||||
mIvRipple.pauseAnimation();
|
||||
mIvRipple.setVisibility(INVISIBLE);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2️⃣ 开始说话(只触发一次)
|
||||
mIvRipple.setVisibility(VISIBLE);
|
||||
iv_on_line.setVisibility(GONE);
|
||||
CommonAppContext.getInstance().onlineMap.put(pitBean.getUser_id(), 1);
|
||||
|
||||
if (!mIvRipple.isAnimating()) {
|
||||
startRippleAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
private void startRippleAnimation() {
|
||||
if (mParser != null) {
|
||||
mIvRipple.startAnimation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (pitBean.getMic_cycle() == null || pitBean.getMic_cycle().isEmpty()) {
|
||||
mIvRipple.startAnimation();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mParser = new SVGAParser(getContext());
|
||||
mParser.decodeFromURL(new URL(pitBean.getMic_cycle()),
|
||||
new SVGAParser.ParseCompletion() {
|
||||
@Override
|
||||
public void onComplete(@NotNull SVGAVideoEntity svgaVideoEntity) {
|
||||
if (mIvRipple == null) return;
|
||||
mIvRipple.setImageDrawable(new SVGADrawable(svgaVideoEntity));
|
||||
mIvRipple.startAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {}
|
||||
});
|
||||
} catch (MalformedURLException ignored) {}
|
||||
}
|
||||
|
||||
public void setCharm(String charm) {
|
||||
mCharmView.setSex(pitBean.getSex(), pitBean.getUser_id(), charm, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user