被这个The surface has been released错误纠缠了2天,今天终于解决了,现在整理下思路。

自己练手做了个项目,使用SurfaceView播放视频。但是测试时发现如果播放时来电话,通话结束后不能自动播放。经过百度,重写了onPush和onResume方法,测试通过。但是此时如果按HOME键,再切换回主程序时,视频不能自动播放,并且会报The surface has been released这个错误。

各位大神的见解基本都差不多,说是 在surfaceHolder还没准备好的时候,就调用了MediaPlayer的start()方法。并建议将mediaPlayer.setDisplay(surfaceHolder)放在surfaceCreated中,自己尝试了下,问题并没有解决。最后经过多方查阅,才知道surface的创建在onResume方法之后,但是我确是在onResume方法之中调用的play方法,因此必然会报这个错。

好的,既然知道了问题,那么答案也就在眼前了,我的解决思路是,不采用onPush和onResume这两个方法来判断应用是否在前台。而是用surfaceHolder.addCallback(new SurfaceCallback());来监听,通过surfaceCreated和surfaceDestroyed这两个方法来判断。当然,这样只是解决了HOME键返回的问题,当来电话时是不会调用这两个方法的(但是onPush和onResume方法却会调用,很奇怪,不知道为什么),所以接下来要做的是对来电进行监听。

//获取电话服务
        manager = (TelephonyManager) this.getSystemService(TELEPHONY_SERVICE);
        // 手动注册对PhoneStateListener中的listen_call_state状态进行监听
        manager.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);



创建MyPhoneStateListener类,由于OFFHOOK是主动挂断电话,API中没有被动挂断这一状态,所以只能定义一个isCalling用来判断被动挂断这种情况。

private class MyPhoneStateListener extends PhoneStateListener{
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            //需要考虑主动挂断和被动挂断两种情况
            switch (state){
                //空闲
                case TelephonyManager.CALL_STATE_IDLE:
                    System.out.println("电话处于空闲状态......");
                    //判断通话是否为对方挂断
                    if (isCalling) {
                        if (position > 0 && path != null) {
                            play(position);
                            position = 0;
                        }
                    }
                    isCalling = false;
                    break;
                //来电
                case TelephonyManager.CALL_STATE_RINGING:
                    System.out.println("电话呼入......电话号码是:"+incomingNumber);
                    if (mediaPlayer.isPlaying()) {
                        position = mediaPlayer.getCurrentPosition();
                        mediaPlayer.stop();
                    }
                    isCalling = true;
                    break;
                //主动挂断
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    System.out.println("电话挂断......");
                    if (position > 0 && path != null) {
                        play(position);
                        position = 0;
                    }
                    break;
            }
            super.onCallStateChanged(state, incomingNumber);
        }
    }


最后,千万别忘了注册权限

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

现在。OK,大功告成,无论是电话进来,还是按HOME键返回,当程序切换回来的时候,视频都可以继续播放了!


最后,如果我的经验对你有用,不要吝啬你宝贵的支持,在下面回复下吧!