Skip to content Skip to sidebar Skip to footer

The Surface Has Been Released When I Try To Setdisplay To Mediaplayer

My xml file: M

Solution 1:

The Surface can be destroyed. That's why you need to add to the a public void surfaceDestroyed(SurfaceHolder holder) to your SurfaceView's implementation like this:

@OverridepublicvoidsurfaceDestroyed(SurfaceHolder holder) {
    synchronized (this) {
        hasActiveHolder = false;

        synchronized(this)          {
              this.notifyAll(); 
        }
    } 
}

You should also add a function that handles Surface creation:

@OverridepublicvoidsurfaceCreated(SurfaceHolder holder) {
     synchronized (this) {
        hasActiveHolder = true;
        this.notifyAll()
     }
}

And modify your own function this way:

    mp.setDataSource("sdcard/test/a.3gp");
    SurfaceHoldersh= sv.getHolder();
    synchronized (this) {
       while (!hasActiveHolder) {
              try {
                  this.wait();
              } catch (InterruptedException e) {
                //Print something
              }
        }
        mp.setDisplay(sh);
        mp.prepare();
    }

You have another option which is the way Google suggests you use SurfaceView: in a separate thread.

Solution 2:

It's something related to the sequence of executing, as the surface has to be created first before setting display for the MediaPlayer, so you have to override the callback method surfaceCreated to the following:

@OverridepublicvoidsurfaceCreated(SurfaceHolder holder) {
    mp.setDisplay(sh); // now "mp" is defined as a class variable
}

and now there is no need to setDisplay inside your play method:

private MediaPlayer mp; // to use it inside surfaceCreated callback methodpublicvoidplayVideo() {
    mp = newMediaPlayer();
    SurfaceViewsv= (SurfaceView) this.findViewById(R.id.surfaceView);
    try {
        mp.setDataSource("sdcard/test/a.3gp");
        SurfaceHoldersh= sv.getHolder();
        mp.prepare();
        mp.start();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Solution 3:

The simplest way is just to call setDisplay in surfaceCreated:

@OverridepublicvoidsurfaceCreated(SurfaceHolder holder) {
    mp.setDisplay(holder)
}

and don't forget to unbind surface:

@OverridepublicvoidsurfaceDestroyed(SurfaceHolder holder) {
    mp.setDisplay(null);
}

Note: media player should be initialized somewhere before, for example in onCreate.

Solution 4:

Make use of SurfaceHolder.Callback as below

SurfaceViewmSurfaceView= (SurfaceView) findViewById(R.id.surfaceView);
SurfaceHolderholder= mSurfaceView.getHolder();
finalMediaPlayerplayer=newMediaPlayer();

holder.addCallback(newSurfaceHolder.Callback() {
    @OverridepublicvoidsurfaceCreated(SurfaceHolder holder) {
        player.setDisplay(holder);
    }

    @OverridepublicvoidsurfaceChanged(SurfaceHolder holder, int format, int width, 
    int height) {

    }

    @OverridepublicvoidsurfaceDestroyed(SurfaceHolder holder) {

    }
});

String UrlPath="android.resource://"+getActivity().getPackageName()+"/"+R.raw.your_file_name_without_extension;
try {
    player.setDataSource(getActivity(),Uri.parse(UrlPath));
    player.prepareAsync();
} catch (IOException e) {
    e.printStackTrace();
}
player.setOnPreparedListener(newMediaPlayer.OnPreparedListener() {

    @OverridepublicvoidonPrepared(MediaPlayer mp) {
        mp.start();
    }
});

Solution 5:

For those still having issues, try implementing SurfaceHolder.Callback in your activity/fragment/etc and at the onCreate/onCreateView method, call the addCallback(SurfaceHolder.Callback callback) method, using your activity/fragment/etc as the parameter callback.

Post a Comment for "The Surface Has Been Released When I Try To Setdisplay To Mediaplayer"