播放视频背景时,报android.view.WindowManager$BadTokenException:Unable to add window-token null is not valid;

when Playing the video background, report android.view.WindowManager$BadTokenException:Unable to add window-token null is not valid;

我正在尝试使用实时数据库在 recyclerView 中播放 VideoView 中的视频。 这是我的 recyclerView 适配器代码。 :-

    class VideoAdapter(private var mContext: Context,private var mvideos: List<VID>) : RecyclerView.Adapter<VideoAdapter.ViewHolder>() {override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {val view = LayoutInflater.from(mContext).inflate(R.layout.videos_adapter, parent, false)return ViewHolder(view)}

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val videoid = mvideos[position]
    
        holder.vidId.text = videoid.getilp()
    
        val videolink = Uri.parse(videoid.getVideoUrl())
        val mediaController = MediaController(mContext)
        mediaController.setAnchorView(holder.videoIv)
        holder.videoIv.setMediaController(mediaController)
        holder.videoIv.setVideoURI(videolink)
        holder.videoIv.requestFocus()
        holder.videoIv.start()
    }
    
    override fun getItemCount(): Int {
        return mvideos.size
    }
    
    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var videoIv: VideoView = itemView.videos_ret
        var vidId: TextView = itemView.videos_id_ret
    }

 }

使用此代码后。我收到此错误。

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running? at android.view.ViewRootImpl.setView(ViewRootImpl.java:1444) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:469) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:114) at android.widget.MediaController.show(MediaController.java:384)
at android.widget.MediaController.show(MediaController.java:334)
at android.widget.VideoView.onPrepared(VideoView.java:521)
at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:4228) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:246) at android.app.ActivityThread.main(ActivityThread.java:8653) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

它在崩溃后在后台播放视频几秒钟,然后才关闭应用程序。 有人,请帮助我。

添加到 window 的视图必须有一个令牌,在您的情况下,它是 activity。但是当你的应用程序在后台时,它可能会被系统销毁。您可以在 activity onDestory 方法

中添加日志信息

在大多数场景中,当 activity 生命周期处于 onPause 时,视频播放应该暂停。如果一定要玩,那就换一种方式使用吧。

PIP, 你也可以使用一些第三方库。

PiP leverages the multi-window APIs made available in Android 7.0 to provide the pinned video overlay window. To add PiP to your app, you need to register your activities that support PiP, switch your activity to PiP mode as needed, and make sure UI elements are hidden and video playback continues when the activity is in PiP mode. The PiP window appears in the topmost layer of the screen, in a corner chosen by the system.

而不是 VideoView 使用 Exoplayer:-

class VideoAdapter(
    private var mContext: Context,
    private var mvideos: List<VID>
) : RecyclerView.Adapter<VideoAdapter.ViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(mContext).inflate(R.layout.videos_adapter, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val videoid = mvideos[position]

        holder.vidId.text = videoid.getilp()

        val dataSourceFactory: DataSource.Factory = DefaultHttpDataSource.Factory()
        val videoLink = Uri.parse(videoid.getVideoUrl())
        val mediaSource: MediaSource = ProgressiveMediaSource.Factory(dataSourceFactory)
            .createMediaSource(MediaItem.fromUri(videoLink))

        holder.mPlayer = SimpleExoPlayer.Builder(mContext).build()
        holder.playerView.player = holder.mPlayer
        holder.mPlayer!!.playWhenReady = true
        holder.mPlayer!!.setMediaSource(mediaSource)
        holder.mPlayer!!.stop()
    }

    override fun getItemCount(): Int {
        return mvideos.size
    }

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var mPlayer: SimpleExoPlayer? = null
        var playerView: PlayerView = itemView.videos_ret
        var vidId: TextView = itemView.videos_id_ret
    }

}