在另一个方法中使用SurfaceView addCallback()而不是在onCreate()中使用

时间:2016-06-13 17:39:40

标签: java android surfaceview

我想从服务器获取视频路径,然后使用surfaceView播放它们。

如果我使用其他活动类在收到路径后播放视频,我可以这样做。但是我想尝试同样的活动。

我使用AsyncTask在后台获取路径。此AsyncTask在onCreate()方法中执行。在onPostExecute()中获取路径后,我想在SurfaceView中播放视频。

但SurfaceView是在我收到这些路径之前创建的。所以我尝试在onPostExecute()中使用SurfaceView的addCallback()。但看起来不可能。

我是怎么做到的?使用SurfaceView后,从服务器获取资源路径后,无法在同一活动上播放视频吗?

1 个答案:

答案 0 :(得分:1)

是的,我找到了解决方案。我会在这里发布,以便它会对像我这样的人有所帮助。因为无处不在,我为此检查了一个解决方案,没有采用这种方式。

您的活动类:

public class PlayActivity extends AppCompatActivity implements SurfaceHolder.Callback {
    private SurfaceHolder sh;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_play);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        //getResource is your AsyncTask
        //I will not post it here because it is not the problem we had
        getResource _gR = new attemptGetStream(p1, p2);
        _gR.execute();

        //initiate components
        SurfaceView sV = (SurfaceView) findViewById(R.id.main);
        assert null != sV : "Surface is null";
        sV.getHolder().addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder sHolder) {
        //this is the solution.
        //only assign holder to a variable but don’t initiate MediaPlayer here
        //because we don’t have resource paths yet
        //we will initiate MediaPlayer in postExecute method and
        //attach to this holder from there
        sh = sHolder;
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
        log("Surface changed");
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        log("Surface destroyed");
    }

    //this is our method called from onPostExecute() in our getResource AsyncTask
    public void play(String path){
        //here initiate the MediaPlayer and assign dataSource
        //attach the player to sh(which is our surface holder
        try{
            MediaPlayer mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setDisplay(sh);//sh is the surface holder
            mMediaPlayer.setDataSource(getApplicationContext(), path);//path is what we got from onPostExecute method in AsyncTask

            mMediaPlayer.prepareAsync();//i use prepareAsync method here so it will not hog the phone
            mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mP.start();
                }
            });
        }catch (Exception e){//use exception types as you like
            e.printStackTrace();
        }
    }


}