Android中如何停止工作线程?现有方案失效求助
问题分析与修复方案
核心问题
你遇到的问题根源有两个:
- 自定义的
stopping()方法错误中断了调用线程(UI线程),而非等待线程本身; - 线程中断逻辑不严谨,且未在启动新视频时正确终止旧的等待线程。
修复方案1:正确改造等待线程
修改等待线程的停止逻辑,确保中断目标线程,并结合volatile标志位保证线程安全:
private class waitingThread extends Thread{ private volatile boolean isRunning = true; // 保证多线程下状态可见性 private int timeCount = 0; @Override public void run() { timeCount = 0; // 启动前重置计数 try { while (isRunning && !isInterrupted()) { timeCount++; Thread.sleep(1000); Log.d(TAG, "Time count : " + timeCount); if(timeCount >= 120){ // finish()必须在UI线程执行 runOnUiThread(() -> finish()); break; } } } catch (InterruptedException e) { // 捕获中断后重置中断状态,确保循环正常退出 Thread.currentThread().interrupt(); } finally { timeCount = 0; isRunning = true; // 重置标志位,方便线程复用(可选) } } // 正确的停止方法:中断当前线程实例+设置终止标志 public void stopWaiting() { isRunning = false; this.interrupt(); } }
然后在Activity中调整线程调用逻辑,确保启动新视频时终止旧线程:
// 将w8改为Activity成员变量,而非局部变量 private waitingThread w8; // 视频准备播放时,终止等待线程 videoView.setOnPreparedListener(mediaPlayer -> { // 终止正在运行的等待线程 if (w8 != null && w8.isAlive()) { w8.stopWaiting(); } // 原有的播放参数设置 PlaybackParams playbackParams = new PlaybackParams(); playbackParams.setSpeed(DeviceConfig.getInstance().getVideoPeed()); mediaPlayer.setPlaybackParams(playbackParams); videoView.start(); }); // 视频播放完成时,启动新的等待线程 videoView.setOnCompletionListener(mediaPlayer -> { // 先终止旧线程(防止重复启动) if (w8 != null && w8.isAlive()) { w8.stopWaiting(); } w8 = new waitingThread(); w8.start(); });
替代方案2:使用Handler实现延迟任务(更简洁)
避免手动管理线程,改用Android自带的Handler实现延迟退出逻辑,代码更简洁且不易出错:
private Handler exitHandler = new Handler(Looper.getMainLooper()); private Runnable exitRunnable = () -> finish(); // 视频播放完成时启动120秒延迟退出任务 videoView.setOnCompletionListener(mediaPlayer -> { exitHandler.postDelayed(exitRunnable, 120 * 1000); }); // 视频准备播放或用户选择新视频时,取消延迟任务 videoView.setOnPreparedListener(mediaPlayer -> { exitHandler.removeCallbacks(exitRunnable); // 原有的播放参数设置 PlaybackParams playbackParams = new PlaybackParams(); playbackParams.setSpeed(DeviceConfig.getInstance().getVideoPeed()); mediaPlayer.setPlaybackParams(playbackParams); videoView.start(); }); // Activity销毁时清理任务,防止内存泄漏 @Override protected void onDestroy() { super.onDestroy(); exitHandler.removeCallbacksAndMessages(null); }
内容的提问来源于stack exchange,提问作者Jamebes
相关产品推荐
相关产品推荐

