1:优化礼物播放和下载方式

2:优化转盘展示效果
This commit is contained in:
2025-08-29 01:14:35 +08:00
parent ae4dc34da4
commit 6a0379e418
8 changed files with 236 additions and 148 deletions

View File

@@ -48,6 +48,7 @@ import com.xscm.moduleutil.utils.SpUtil;
import com.xscm.moduleutil.utils.logger.Logger;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.URL;
@@ -56,6 +57,13 @@ import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
public class AvatarFrameView extends FrameLayout implements IAnimListener {
@Override
@@ -322,142 +330,151 @@ public class AvatarFrameView extends FrameLayout implements IAnimListener {
return memoryUsage > 0.8 || usedMemory > MAX_MEMORY_THRESHOLD;
}
// public void setSource(String url, int type2) {
// if (SpUtil.getOpenEffect()==1) {
// playQueue.offer(new PlayItem(url, type2));
// if (!isPlaying) {
// playNextFromQueue();
// }
// }else {
// playQueue.clear();
// isPlaying = false;
// }
//
//// RenderType type = null;
//// if ("svga".equalsIgnoreCase(getFileExtension(url))){
//// type = RenderType.SVGA;
//// }else if ("mp4".equalsIgnoreCase(getFileExtension(url))){
//// type = RenderType.MP4;
//// }
////
//// clearPrevious();
//// renderType = type;
//// mType = type2;
//// switch (type) {
//// case SVGA:
//// mBinding.playView.stopPlay();
//// mBinding.playView.setVisibility(View.GONE);
//// loadSVGA(url);
//// break;
//// case MP4:
////// loadMP4(url);
//// mBinding.playView.setVisibility(View.VISIBLE);
//// downloadAndPlayMp4(url);
//// break;
//// }
// }
boolean isTxk = false;
private void downloadAndPlayMp4(String url) {
String filePath = PathUtils.getInternalAppCachePath() + Md5Utils.getStringMD5(url) + ".mp4";
// 提取文件名
String fileName = url.substring(url.lastIndexOf("/"));
String filePath = getContext().getCacheDir().getAbsolutePath() + fileName;
File file = new File(filePath);
if (file.exists() && file.length() > 0) {
playMp4(file);
mFile = file;
} else {
// 删除可能存在的损坏文件
// if (file.exists()) {
// file.delete();
// }
DownloadTask task = new DownloadTask.Builder(url, PathUtils.getInternalAppCachePath()
, Md5Utils.getStringMD5(url) + ".mp4")
.setMinIntervalMillisCallbackProcess(300)
.setPassIfAlreadyCompleted(true)
.setAutoCallbackToUIThread(true)
.setConnectionCount(3) // 增加连接数提高稳定性
.setReadBufferSize(1024 * 8) // 增大缓冲区
if (!file.exists()) {
LogUtils.e("无缓存");
// 使用OkHttp进行下载
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
if (StatusUtil.isCompleted(task)) {
playMp4(task.getFile());
mFile = task.getFile();
} else if (StatusUtil.isSameTaskPendingOrRunning(task)) {
// 如果任务正在进行中,等待完成
// 可以通过监听器处理
attachToExistingTask(task);
} else {
task.enqueue(new DownloadListener1() {
@Override
public void taskStart(@NonNull DownloadTask task, @NonNull Listener1Assist.Listener1Model model) {
Logger.e("AvatarFrameView1", model);
}
@Override
public void retry(@NonNull DownloadTask task, @NonNull ResumeFailedCause cause) {
Logger.e("AvatarFrameView2", cause);
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d("sssssssssss", e.toString());
}
}
@Override
public void connected(@NonNull DownloadTask task, int blockCount, long currentOffset, long totalLength) {
Logger.e("AvatarFrameView3", blockCount);
}
@Override
public void progress(@NonNull DownloadTask task, long currentOffset, long totalLength) {
Logger.e("AvatarFrameView4", currentOffset);
}
@Override
public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause, @NonNull Listener1Assist.Listener1Model model) {
Logger.e("AvatarFrameView5", model);
// playMp4(task.getFile());
// mFile = task.getFile();
// if (cause != null && cause != EndCause.COMPLETED) {
//// CrashReport.postCatchedException(new RuntimeException("下载任务结束:" + cause == null ? "" : cause.name() + "_realCause:" + realCause == null ? "" : realCause.getMessage()));
// }
if (cause == EndCause.COMPLETED) {
File downloadedFile = task.getFile();
if (downloadedFile != null && downloadedFile.exists() && downloadedFile.length() > 0) {
playMp4(downloadedFile);
mFile = downloadedFile;
} else {
Logger.e(TAG, "Downloaded file is invalid");
handleDownloadFailure(url, cause, new IOException("Downloaded file is invalid"));
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
// 保存文件到缓存目录
try (ResponseBody responseBody = response.body()) {
if (responseBody != null) {
File downloadedFile = new File(filePath);
FileOutputStream fos = new FileOutputStream(downloadedFile);
fos.write(responseBody.bytes());
fos.close();
isTxk=true;
// 在主线程中播放动画
mainHandler.post(() -> {
if (isTxk) {
mBinding.playView.setLoop(20);
}
mBinding.playView.startPlay(downloadedFile);
});
}
} else {
handleDownloadFailure(url, cause, realCause);
}
}
});
}
});
} else {
isTxk=true;
LogUtils.e("有缓存");
// 直接播放缓存文件
if (isTxk) {
mBinding.playView.setLoop(20);
}
mBinding.playView.startPlay(file);
}
}
private void handleDownloadFailure(String url, EndCause cause, Exception realCause) {
Logger.e(TAG, "Download failed: " + cause + ", real cause: " + realCause);
// 尝试重试一次
mainHandler.postDelayed(() -> {
// 检查队列是否仍然包含这个项目
boolean shouldRetry = false;
for (PlayItem item : playQueue) {
if (item.url.equals(url)) {
shouldRetry = true;
break;
}
}
if (shouldRetry) {
// 重新添加到队列开头
playQueue.add(new PlayItem(url, mType));
playNextFromQueue();
} else {
isPlaying = false;
playNextFromQueue();
}
}, 1000); // 1秒后重试
}
// private void downloadAndPlayMp4(String url) {
// String filePath = PathUtils.getInternalAppCachePath() + Md5Utils.getStringMD5(url) + ".mp4";
// File file = new File(filePath);
//
// if (file.exists() && file.length() > 0) {
// playMp4(file);
// mFile = file;
// } else {
// // 删除可能存在的损坏文件
//// if (file.exists()) {
//// file.delete();
//// }
//
// DownloadTask task = new DownloadTask.Builder(url, PathUtils.getInternalAppCachePath()
// , Md5Utils.getStringMD5(url) + ".mp4")
// .setMinIntervalMillisCallbackProcess(300)
// .setPassIfAlreadyCompleted(true)
// .setAutoCallbackToUIThread(true)
// .setConnectionCount(3) // 增加连接数提高稳定性
// .setReadBufferSize(1024 * 8) // 增大缓冲区
// .build();
// if (StatusUtil.isCompleted(task)) {
// playMp4(task.getFile());
// mFile = task.getFile();
// } else if (StatusUtil.isSameTaskPendingOrRunning(task)) {
// Logger.d(TAG, "Task is pending or running, checking if it's stuck");
// // 检查任务是否可能卡住了
// // 添加超时机制,如果任务长时间没有进展,则重新开始
// checkAndHandleStuckTask(task, url);
// } else {
// Logger.d(TAG, "Starting new download task");
// startNewDownload(task, url);
// }
//
//// else if (StatusUtil.isSameTaskPendingOrRunning(task)) {
//// // 如果任务正在进行中,等待完成
//// // 可以通过监听器处理
//// attachToExistingTask(task);
//// } else {
//// task.enqueue(new DownloadListener1() {
//// @Override
//// public void taskStart(@NonNull DownloadTask task, @NonNull Listener1Assist.Listener1Model model) {
//// Logger.e("AvatarFrameView1", model);
//// }
////
//// @Override
//// public void retry(@NonNull DownloadTask task, @NonNull ResumeFailedCause cause) {
//// Logger.e("AvatarFrameView2", cause);
////
//// }
////
//// @Override
//// public void connected(@NonNull DownloadTask task, int blockCount, long currentOffset, long totalLength) {
//// Logger.e("AvatarFrameView3", blockCount);
//// }
////
//// @Override
//// public void progress(@NonNull DownloadTask task, long currentOffset, long totalLength) {
//// Logger.e("AvatarFrameView4", currentOffset);
//// }
////
//// @Override
//// public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause, @NonNull Listener1Assist.Listener1Model model) {
//// Logger.e("AvatarFrameView5", model);
////// playMp4(task.getFile());
////// mFile = task.getFile();
////// if (cause != null && cause != EndCause.COMPLETED) {
//////// CrashReport.postCatchedException(new RuntimeException("下载任务结束:" + cause == null ? "" : cause.name() + "_realCause:" + realCause == null ? "" : realCause.getMessage()));
////// }
////
//// if (cause == EndCause.COMPLETED) {
//// File downloadedFile = task.getFile();
//// if (downloadedFile != null && downloadedFile.exists() && downloadedFile.length() > 0) {
//// playMp4(downloadedFile);
//// mFile = downloadedFile;
//// } else {
//// Logger.e(TAG, "Downloaded file is invalid");
//// handleDownloadFailure(url, cause, new IOException("Downloaded file is invalid"));
//// }
//// } else {
//// handleDownloadFailure(url, cause, realCause);
//// }
//// }
//// });
//// }
// }
// }
// 添加检查进行中任务的方法
private void attachToExistingTask(DownloadTask task) {
// 为已经在队列中的任务附加监听器
@@ -802,7 +819,7 @@ public class AvatarFrameView extends FrameLayout implements IAnimListener {
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
protected boolean removeEldestEntry(Entry<K, V> eldest) {
return size() > maxSize;
}
}

View File

@@ -154,6 +154,7 @@ public class GiftCardView extends FrameLayout {
}
}
}
private android.animation.AnimatorSet animatorSet;
public void startPulseAnimationWithLayer() {
if (pulseAnimator != null && pulseAnimator.isRunning()) {
@@ -169,7 +170,7 @@ public class GiftCardView extends FrameLayout {
scaleYAnimator.setRepeatMode(ObjectAnimator.REVERSE);
// 组合动画
android.animation.AnimatorSet animatorSet = new android.animation.AnimatorSet();
animatorSet = new android.animation.AnimatorSet();
animatorSet.playTogether(pulseAnimator, scaleYAnimator);
animatorSet.start();
}
@@ -178,8 +179,22 @@ public class GiftCardView extends FrameLayout {
if (pulseAnimator != null) {
pulseAnimator.cancel();
}
// 停止组合动画
if (animatorSet != null && animatorSet.isRunning()) {
animatorSet.cancel();
}
// 清除引用
animatorSet = null;
pulseAnimator = null;
// 重置缩放
this.setScaleX(1f);
this.setScaleY(1f);
// 强制重新绘制
this.invalidate();
}
/**
* 设置礼物名称