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

Android Studio中VideoView横屏旋转后视频从头播放问题排查

解决Android屏幕旋转时视频从头播放的问题

问题原因

你的代码未生效核心有两个问题:

  1. 调用时机错误:onRestoreInstanceState执行时机晚于initVideoView里的binding.videoView.start(),视频已经从头开始播放后才调用seekTo,进度设置被覆盖。
  2. 未在视频就绪后设置进度:seekTo需要在VideoView完成视频资源加载后调用,否则视频未就绪,进度设置不会生效。

修复后的完整代码

package com.example.videoview

import android.net.Uri
import android.os.Bundle
import android.widget.MediaController
import androidx.appcompat.app.AppCompatActivity
import com.example.videoview.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private var playbackPosition = 0
    private var isVideoPlaying = false // 记录播放状态

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 从savedInstanceState中恢复进度和播放状态
        savedInstanceState?.let {
            playbackPosition = it.getInt("position")
            isVideoPlaying = it.getBoolean("isPlaying")
        }

        initVideoView()
    }

    private fun initVideoView() {
        val uri = Uri.parse("android.resource://$packageName/${R.raw.paris_video}")
        val controller = MediaController(this)

        binding.videoView.setMediaController(controller)
        binding.videoView.setVideoURI(uri)

        binding.videoView.setOnPreparedListener { mediaPlayer ->
            mediaPlayer.setOnVideoSizeChangedListener { _, _, _ ->
                controller.setAnchorView(binding.videoView)
            }

            // 视频准备完成后,跳转到保存的进度
            if (playbackPosition > 0) {
                binding.videoView.seekTo(playbackPosition)
            }

            // 根据之前的状态决定是否继续播放
            if (isVideoPlaying) {
                binding.videoView.start()
            }
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        // 保存当前进度和播放状态
        outState.putInt("position", binding.videoView.currentPosition)
        outState.putBoolean("isPlaying", binding.videoView.isPlaying)
    }
}

关键修改点

  • 提前恢复状态:在onCreate中直接从savedInstanceState读取进度和播放状态,避免依赖onRestoreInstanceState的滞后执行。
  • 就绪后设置进度:将进度跳转和播放逻辑移到OnPreparedListener回调内,确保视频资源加载完成后再执行操作。
  • 记录播放状态:新增isVideoPlaying变量,避免旋转后手动暂停的视频自动播放。

额外优化方案

如果你的页面布局简单,不需要依赖系统重建适配横竖屏,可以在AndroidManifest.xml中给Activity添加配置,让屏幕旋转时不重建Activity:

<activity
    android:name=".MainActivity"
    android:configChanges="orientation|screenSize">
    <!-- 其他属性 -->
</activity>

这种方式下视频会自动适配屏幕,无需手动处理进度保存,但会失去系统自动重建带来的布局适配能力。

内容的提问来源于stack exchange,提问作者Alex Pit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 14:22:37