You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:59:03