CHETAN
CHETAN

Reputation: 602

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

I am trying to play videos in VideoView in the recyclerView using realTime database. Here is my adapter code of the 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
    }

 }

After using this code. I am getting this error.

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$2.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)

It plays the video for a few seconds in the background after crashing before closing the app. someone, please help me.

Upvotes: 1

Views: 298

Answers (2)

CHETAN
CHETAN

Reputation: 602

Instead of VideoView use 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
    }

}

Upvotes: 0

Lenoarod
Lenoarod

Reputation: 3620

The view added to the window must have a token, in your situation, it is the activity. but when your application is in the background, it may be destroyed by the system. you can add log info in the activity onDestory method

in most scenes, when the activity lifecycle is in onPause, the video play should pause. if you have to play it, you should change the way you use it.

it is PIP, you can also use some third library.

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.

Upvotes: 0

Related Questions