Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VideoView doesn't start when invisible

I have an AsyncTask, where I hide a video view, start the video playback, and show the video view when the video is playing.

But the video would just not start when the video view is set to invisible, the async task keeps hanging in onBackground. If I comment out this line, the video starts playing. Why does the video view require a visible surface?

public void walk(final View v) {

    new AsyncTask() {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mVideoView.setVisibility(View.INVISIBLE); // this line causes video not to start
            mVideoView.start();
        }

        @Override
        protected Object doInBackground(Object... objects) {
            while (!mVideoView.isPlaying()) {}
            return null;
        }

        @Override
        protected void onPostExecute(Object o) {
            super.onPostExecute(o);
            mVideoView.setVisibility(View.VISIBLE);
        }

    }.execute();

A bit of background why I'm doing this: I try to avoid the well-known issue of the black flash that you usually have when starting a video:

https://stackoverflow.com/search?q=%5Bandroid%5D+videoview+black

https://stackoverflow.com/search?q=%5Bandroid%5D+video+%5Bmediaplayer%5D+black

like image 427
Mathias Conradt Avatar asked Nov 28 '11 04:11

Mathias Conradt


1 Answers

The VideoView is really a specialised SurfaceView. A SurfaceView works by creating another window behind the normal window (containing all of the views), and then having an area of transparency so that the new window (with its own drawing surface) can be seen behind it.

If a SurfaceView is no longer visible, its surface will be destroyed i.e. SurfaceHolder.Callback.surfaceDestroyed is called. The VideoView will not try to play its video if there is not a valid surface, hence your AsyncTask will be able to never leave doInBackground.

The Surface will be created for you while the SurfaceView's window is visible; you should implement surfaceCreated(SurfaceHolder) and surfaceDestroyed(SurfaceHolder) to discover when the Surface is created and destroyed as the window is shown and hidden.

like image 156
antonyt Avatar answered Nov 09 '22 22:11

antonyt