Android Studio报错:getCurrentPosition需在UI线程调用,当前为工作线程
解决AsyncTask中调用VideoView.getCurrentPosition()的线程错误
这个报错的核心原因非常清晰:Android的UI组件相关方法(比如VideoView的getCurrentPosition())必须在UI线程执行,而你在AsyncTask的doInBackground()方法里调用了它——这个方法是运行在后台工作线程的,所以系统直接抛出了线程检查异常。
下面给你两种可行的修复方案:
方案1:将UI操作移至onProgressUpdate方法
AsyncTask的onProgressUpdate()本身就是在UI线程执行的,我们可以把获取视频进度的操作放到这里,后台线程只负责定时触发更新:
public class VideoProgress extends AsyncTask<Void, Integer, Void> { @Override protected Void doInBackground(Void... voids) { do { if (isPlaying) { // 仅触发进度更新回调,不执行UI操作 publishProgress(); // 添加短延迟,避免过于频繁触发更新 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } while (currentProgress.getProgress() <= 100 && isPlaying); return null; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); // 此处处于UI线程,安全调用getCurrentPosition() if (isPlaying) { int current = vv.getCurrentPosition() / 1000; currentProgress.setProgress(current); } } }
方案2:用runOnUiThread切换到UI线程执行
如果不想大幅调整代码结构,也可以在doInBackground()里通过Activity.runOnUiThread()包裹UI相关调用:
public class VideoProgress extends AsyncTask<Void, Integer, Void> { private Activity mActivity; // 需要传入当前Activity的引用 public VideoProgress(Activity activity) { mActivity = activity; } @Override protected Void doInBackground(Void... voids) { do { if (isPlaying) { mActivity.runOnUiThread(new Runnable() { @Override public void run() { // 在UI线程内获取进度并发布 int current = vv.getCurrentPosition() / 1000; publishProgress(current); } }); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } while (currentProgress.getProgress() <= 100 && isPlaying); return null; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); currentProgress.setProgress(values[0]); } }
额外注意事项
- 记得在视频停止播放或Activity销毁时,调用
videoProgressTask.cancel(true)取消AsyncTask,避免内存泄漏和无效的后台操作。 - AsyncTask已经被标记为Deprecated,长期来看更推荐使用
Coroutine或Handler来实现这类定时UI更新任务,兼容性和可维护性更好。
内容的提问来源于stack exchange,提问作者TommyLau
相关产品推荐
相关产品推荐

